通過jndi程式設計rmi實現和操作檔案的實現 以及jndi的spi實現
JNDI是java提供的命名介面服務,需要第三方公司按照SPI所提供的服務實現,FSSP的官方資源包下載地址;
http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#7110-jndi-1.2.1-oth-JPR
例子1:SUN公司官方提供的檔案系統服務提供者
將fscontext.jar和providerutil.jar載入到classpath下
程式碼例子:
public class FSSPTest {
public static void main(String[] args) throws NamingException {
// TODO Auto-generated method stub
Hashtable<String,String> env = new Hashtable<>();
//指明初始化的factory是我們下載的jar包中的RefFSContextFactory
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
//指明Context的初始URL,這裡我們的是C盤
env.put(Context.PROVIDER_URL,"file:///c:/");
Context ctx = new InitialContext(env);
//在C盤下建立要給資料夾名為JesminDir
ctx.createSubcontext("JesminDir");
//在C盤下定位myFile檔案
File f = (File) ctx.lookup("myFile");
System.out.println(f);
//列出當前context下的所有元素的名稱和型別(包括資料夾和檔案)
NamingEnumeration list = ctx.list("/");
while (list.hasMore()) {
NameClassPair nc = (NameClassPair)list.next();
System.out.println(nc);
}
}
}
例子2:RMI
實現RMI的程式有兩種方式
方式一:通過jndi實現需要jar:providerutil.jar和rmiregistry.jar
user介面
package com;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface UserI extends Remote{
public String getName() throws RemoteException ;
}
user實現類
package com;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class UserImp extends UnicastRemoteObject implements UserI{
protected UserImp() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
@Override
public String getName() throws RemoteException{
// TODO Auto-generated method stub
return "yang";
}
}
RMI 服務端:
package com;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
public class RmiServer {
public static void main(String[] args) {
try {
Hashtable<String,String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory");
env.put(Context.PROVIDER_URL,"rmi://127.0.0.1:8080");
LocateRegistry.createRegistry(8080);
Context txt = new InitialContext(env);
UserI user = new UserImp();
txt.bind("user", user);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
RMI 客戶端:
package com;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
public class RmiClient {
public static void main(String[] args) {
try {
Hashtable<String, Object> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory");
env.put(Context.PROVIDER_URL,"rmi://127.0.0.1:8080");
Context ctx = new InitialContext(env);
UserI user = (UserI)ctx.lookup("user");
System.out.println(user.getName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
方式二:不通過jndi
user介面
package com;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface UserI extends Remote{
public String getName() throws RemoteException ;
}
user實現類
package com;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class UserImp extends UnicastRemoteObject implements UserI{
protected UserImp() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
@Override
public String getName() throws RemoteException{
// TODO Auto-generated method stub
return "yang";
}
}
RMI 服務端:
package com;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RmiServer {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.createRegistry(8080);
UserI user = new UserImp();
registry.bind("user", user);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
RMI 客戶端:
package com;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RmiClient {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 8080);
UserI user = (UserI)registry.lookup("user");
System.out.println(user.getName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
實現SPI的服務例子:
第一步:寫一個factory實現 InitialContextFactory 介面
package examples.spi.flat;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.spi.InitialContextFactory;
public class FlatInitCtxFactory implements InitialContextFactory {
public Context getInitialContext(Hashtable env) {
return new FlatCtx(env);
}
}
第二步:寫FlatCtx實現Context
package examples.spi.flat;
import javax.naming.*;
import java.util.*;
class FlatCtx implements Context {
Hashtable myEnv;
private Hashtable bindings = new Hashtable(11);
static NameParser myParser = new FlatNameParser();
FlatCtx(Hashtable environment) {
myEnv = (environment != null)
? (Hashtable)(environment.clone())
: null;
}
public Object lookup(String name) throws NamingException {
if (name.equals("")) {
// Asking to look up this context itself. Create and return
// a new instance with its own independent environment.
return (new FlatCtx(myEnv));
}
Object answer = bindings.get(name);
if (answer == null) {
throw new NameNotFoundException(name + " not found");
}
return answer;
}
public Object lookup(Name name) throws NamingException {
// Flat namespace; no federation; just call string version
return lookup(name.toString());
}
public void bind(String name, Object obj) throws NamingException {
if (name.equals("")) {
throw new InvalidNameException("Cannot bind empty name");
}
if (bindings.get(name) != null) {
throw new NameAlreadyBoundException(
"Use rebind to override");
}
bindings.put(name, obj);
}
public void bind(Name name, Object obj) throws NamingException {
// Flat namespace; no federation; just call string version
bind(name.toString(), obj);
}
public void rebind(String name, Object obj) throws NamingException {
if (name.equals("")) {
throw new InvalidNameException("Cannot bind empty name");
}
bindings.put(name, obj);
}
public void rebind(Name name, Object obj) throws NamingException {
// Flat namespace; no federation; just call string version
rebind(name.toString(), obj);
}
public void unbind(String name) throws NamingException {
if (name.equals("")) {
throw new InvalidNameException("Cannot unbind empty name");
}
bindings.remove(name);
}
public void unbind(Name name) throws NamingException {
// Flat namespace; no federation; just call string version
unbind(name.toString());
}
public void rename(String oldname, String newname)
throws NamingException {
if (oldname.equals("") || newname.equals("")) {
throw new InvalidNameException("Cannot rename empty name");
}
// Check if new name exists
if (bindings.get(newname) != null) {
throw new NameAlreadyBoundException(newname +
" is already bound");
}
// Check if old name is bound
Object oldBinding = bindings.remove(oldname);
if (oldBinding == null) {
throw new NameNotFoundException(oldname + " not bound");
}
bindings.put(newname, oldBinding);
}
public void rename(Name oldname, Name newname)
throws NamingException {
// Flat namespace; no federation; just call string version
rename(oldname.toString(), newname.toString());
}
public NamingEnumeration list(String name)
throws NamingException {
if (name.equals("")) {
// listing this context
return new FlatNames(bindings.keys());
}
// Perhaps 'name' names a context
Object target = lookup(name);
if (target instanceof Context) {
return ((Context)target).list("");
}
throw new NotContextException(name + " cannot be listed");
}
public NamingEnumeration list(Name name)
throws NamingException {
// Flat namespace; no federation; just call string version
return list(name.toString());
}
public NamingEnumeration listBindings(String name)
throws NamingException {
if (name.equals("")) {
// listing this context
return new FlatBindings(bindings.keys());
}
// Perhaps 'name' names a context
Object target = lookup(name);
if (target instanceof Context) {
return ((Context)target).listBindings("");
}
throw new NotContextException(name + " cannot be listed");
}
public NamingEnumeration listBindings(Name name)
throws NamingException {
// Flat namespace; no federation; just call string version
return listBindings(name.toString());
}
public void destroySubcontext(String name) throws NamingException {
throw new OperationNotSupportedException(
"FlatCtx does not support subcontexts");
}
public void destroySubcontext(Name name) throws NamingException {
// Flat namespace; no federation; just call string version
destroySubcontext(name.toString());
}
public Context createSubcontext(String name)
throws NamingException {
throw new OperationNotSupportedException(
"FlatCtx does not support subcontexts");
}
public Context createSubcontext(Name name) throws NamingException {
// Flat namespace; no federation; just call string version
return createSubcontext(name.toString());
}
public Object lookupLink(String name) throws NamingException {
// This flat context does not treat links specially
return lookup(name);
}
public Object lookupLink(Name name) throws NamingException {
// Flat namespace; no federation; just call string version
return lookupLink(name.toString());
}
public NameParser getNameParser(String name)
throws NamingException {
return myParser;
}
public NameParser getNameParser(Name name) throws NamingException {
// Flat namespace; no federation; just call string version
return getNameParser(name.toString());
}
public String composeName(String name, String prefix)
throws NamingException {
Name result = composeName(new CompositeName(name),
new CompositeName(prefix));
return result.toString();
}
public Name composeName(Name name, Name prefix)
throws NamingException {
Name result = (Name)(prefix.clone());
result.addAll(name);
return result;
}
public Object addToEnvironment(String propName, Object propVal)
throws NamingException {
if (myEnv == null) {
myEnv = new Hashtable(5, 0.75f);
}
return myEnv.put(propName, propVal);
}
public Object removeFromEnvironment(String propName)
throws NamingException {
if (myEnv == null)
return null;
return myEnv.remove(propName);
}
public Hashtable getEnvironment() throws NamingException {
if (myEnv == null) {
// Must return non-null
return new Hashtable(3, 0.75f);
} else {
return (Hashtable)myEnv.clone();
}
}
public String getNameInNamespace() throws NamingException {
return "";
}
public void close() throws NamingException {
myEnv = null;
bindings = null;
}
// Class for enumerating name/class pairs
class FlatNames implements NamingEnumeration {
Enumeration names;
FlatNames (Enumeration names) {
this.names = names;
}
public boolean hasMoreElements() {
return names.hasMoreElements();
}
public boolean hasMore() throws NamingException {
return hasMoreElements();
}
public Object nextElement() {
String name = (String)names.nextElement();
String className = bindings.get(name).getClass().getName();
return new NameClassPair(name, className);
}
public Object next() throws NamingException {
return nextElement();
}
public void close() {
}
}
// Class for enumerating bindings
class FlatBindings implements NamingEnumeration {
Enumeration names;
FlatBindings (Enumeration names) {
this.names = names;
}
public boolean hasMoreElements() {
return names.hasMoreElements();
}
public boolean hasMore() throws NamingException {
return hasMoreElements();
}
public Object nextElement() {
String name = (String)names.nextElement();
return new Binding(name, bindings.get(name));
}
public Object next() throws NamingException {
return nextElement();
}
public void close() {
}
}
};
第三步:寫一個FlatNameParser實現NameParser介面
package examples.spi.flat;
import javax.naming.NameParser;
import javax.naming.Name;
import javax.naming.CompoundName;
import javax.naming.NamingException;
import java.util.Properties;
class FlatNameParser implements NameParser {
static Properties syntax = new Properties();
static {
syntax.put("jndi.syntax.direction", "flat");
syntax.put("jndi.syntax.ignorecase", "false");
}
public Name parse(String name) throws NamingException {
return new CompoundName(name, syntax);
}
}
上面三步已經實現SPI下面是呼叫
package examples.spi.flat;
import java.util.Hashtable;
import javax.naming.*;
class TestFlat {
static void printBindings(String msg, NamingEnumeration bl) {
System.out.println(msg);
if (bl == null)
System.out.println("No items in list");
else {
try {
while (bl.hasMore()) {
Binding b = (Binding)bl.next();
System.out.println(b.getName() + ":" + b.getObject());
}
} catch (NamingException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// Set up to use factory
Hashtable env = new Hashtable(5, 0.75f);
env.put("java.naming.factory.initial",
"examples.spi.flat.FlatInitCtxFactory");
try {
Context initctx = new InitialContext(env);
initctx.bind("a", "binding_a");
initctx.bind("b", "binding_b");
initctx.bind("c", "binding_c");
printBindings("original", initctx.listBindings(""));
// make some changes
initctx.unbind("b");
initctx.rename("a", "aa");
initctx.bind("d", "binding_d");
initctx.rebind("c", "new_binding");
printBindings("after changes", initctx.listBindings(""));
} catch (NamingException e) {
e.printStackTrace();
}
}
}