1. 程式人生 > >通過jndi程式設計rmi實現和操作檔案的實現 以及jndi的spi實現

通過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();
}
}
}