• JNDI


         下面的例子是使用Sun自带的RefFSContextFactory来存储JNDI信息,可以将RefFSContextFactory想象为一个大的HashMap,里面存储了很多对象的信息,需要时只需要从HashMap获取对象即可。

         本例包括4个类,说明如下:

    • BindedClass:自定义的实现Referenceable接口的类
    • BindedClassFactory:工厂类,能够把一个Reference对象转换为BindedClass对象
    • Bind:测试类,用于在JNDI中绑定对象
    • Loopup:测试类,用于从JNDI中获取对象

        首先需要引入fscontext.jar和providerutil.jar,这是进行测试的前提。

    package jndi;
    import javax.naming.NamingException;
    import javax.naming.Reference;
    import javax.naming.Referenceable;
    import javax.naming.StringRefAddr;
    
    public class BindedClass implements Referenceable {
    	public String value;
    
    	public BindedClass() {
    	}
    
    	@Override
    	public Reference getReference() throws NamingException {
    		Reference r = new Reference(this.getClass().getName(), BindedClassFactory.class.getName(), null);
    		r.add(new StringRefAddr("value", this.getValue()));
    		return r;
    	}
    
    	public String getValue() {
    		return value;
    	}
    
    	public void setValue(String value) {
    		this.value = value;
    	}
    
    }
    

      BindedClass类是要存储的类,需要实现Referenceable接口的Reference getReference()方法。该Reference指定了创建BindedClass对象的工厂--BindedClassFactory。

    package jndi;
    
    import java.util.Hashtable;
    import javax.naming.Context;
    import javax.naming.Name;
    import javax.naming.Reference;
    import javax.naming.spi.ObjectFactory;
    
    public class BindedClassFactory implements ObjectFactory {
    	@Override
    	public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
    		if (obj instanceof Reference) {
    			Reference ref = (Reference) obj;
    			String val = (String) ref.get("value").getContent();
    			BindedClass o = new BindedClass();
    			o.setValue(val);
    			return o;
    		}
    		return null;
    	}
    }
    

      BindedClassFactory类将一个Reference对象转换为所需求的BindedClass对象,是创建BindedClass对象具体的类。

    package jndi;
    
    import java.util.Properties;
    import javax.naming.Context;
    import javax.naming.directory.DirContext;
    import javax.naming.directory.InitialDirContext;
    
    public class Bind {
    	public static void main(String[] args) throws Exception {
    		Properties ps = new Properties();
    		ps.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
    		ps.setProperty(Context.PROVIDER_URL, "file:JNDI_REF");
    		DirContext ctx = new InitialDirContext(ps);
    		String key = "bind1";
    
    		BindedClass b = new BindedClass();
    		b.setValue("abcdefg");
    		ctx.rebind(key, b);
    
    		System.out.println("Binded successfully!");
    		ctx.close();
    	}
    }
    

      Bind类用于绑定对象,ps.setProperty(Context.PROVIDER_URL, "file:JNDI_REF");这就要求工程下面有一个名为JNDI_REF的文件夹,其下有一个后缀为.bindings的文件,记录了所绑定对象的信息。

    package jndi;
    
    import java.util.Properties;
    import javax.naming.Context;
    import javax.naming.directory.DirContext;
    import javax.naming.directory.InitialDirContext;
    
    public class Lookup {
    	public static void main(String[] args) throws Exception {
    		Properties ps = new Properties();
    		ps.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
    		ps.setProperty(Context.PROVIDER_URL, "file:JNDI_REF");
    		DirContext ctx = new InitialDirContext(ps);
    		String key = "bind1";
    		BindedClass o = (BindedClass) ctx.lookup(key);
    		System.out.println(o.getValue());
    
    		ctx.close();
    	}
    }
    

      Lookup类用于获取所绑定的对象。Bind类中将对象绑定至bind1,这里就查找bind1获取BindedClass对象。

        先运行Bind类再运行Lookup类,就可以看到成功的获取到了BindedClass对象。

        工程下面有一个名为JNDI_REF的文件夹,其下有一个后缀为.bindings的文件,记录的内容如下:

    bind1/RefAddr/0/Type=value
    bind1/ClassName=lld.test.jndi.BindedClass
    bind1/RefAddr/0/Encoding=String
    bind1/FactoryName=lld.test.jndi.BindedClassFactory
    bind1/RefAddr/0/Content=abcdefg
    

      可以看到该文件记录了绑定类的ClassName,创建绑定类的工厂FactoryName,以及一个类型为String,名为value的属性,可以在创建对象时直接给对象的属性赋值。

        

        数据库的数据源DataSource都实现了Referenceable接口,因此可以通过JNDI来直接获取数据库的数据源,而不必使用JDBC。

        下面是使用JNDI获取MySQL数据连接的例子,需要引入MySQL driver.jar。MysqlDataSource位于MySQL驱动的jar包中。

    package jndi;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Hashtable;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import javax.sql.DataSource;
    
    import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
    
    public class DataSourceJNDI {
    	public static void main(String args[]) throws SQLException {
    		// 初始化名称服务环境
    		Context ctx = null;
    		try {
    			Hashtable env = new Hashtable(5);
    			env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
    			env.put(Context.PROVIDER_URL, "file:JNDI_REF");
    			ctx = new InitialContext(env);
    		} catch (NamingException ne) {
    			ne.printStackTrace();
    		}
    
    		try {
    			 bind(ctx, "jdbc/chidb");
    			lookup(ctx, "jdbc/chidb");
    		} catch (NamingException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    
    	}
    
    	static void bind(Context ctx, String ln) throws NamingException, SQLException {
    		// 创建一个DataSource实例
    		MysqlDataSource ods = new MysqlDataSource();
    
    		ods.setURL("jdbc:mysql://172.16.131.181:13306/NNM5?autoReconnect=true");//需要改为实际的数据库
    		ods.setServerName("Chicago");
    		ods.setDatabaseName("NNM5");
    		ods.setPortNumber(13306);
    		ods.setUser("root");
    		ods.setPassword("OSSDB123");
    
    		// 把DataSource实例注册到JNDI中
    		System.out.println("Doing a bind with the logical name : " + ln);
    		ctx.bind(ln, ods);
    		System.out.println("Successfully bound");
    	}
    
    	static void lookup(Context ctx, String ln) throws NamingException, SQLException {
    		// 从JNDI中查询DataSource实例
    		System.out.println("Doing a lookup with the logical name : " + ln);
    		DataSource ods = (DataSource) ctx.lookup(ln);
    		System.out.println("Successful lookup");
    
    		// 从查询到的DataSource实例中获取数据库连接
    		Connection conn = ods.getConnection();
    		// 进行数据库操作
    		getUserName(conn);
    		// 关闭连接
    		conn.close();
    		conn = null;
    	}
    
    	static void getUserName(Connection conn) throws SQLException {
    		// 生成一个Statement实例
    		Statement stmt = conn.createStatement();
    
    		ResultSet rset = stmt.executeQuery("select propname from rc_properties");
    
    		while (rset.next())
    			System.out.println("Name is " + rset.getString(1));
    
    		rset.close();
    		rset = null;
    
    		stmt.close();
    		stmt = null;
    	}
    }
    

      

         还可以使用其他软件作为JNDI服务器,如WebLogic,tomcat等。

  • 相关阅读:
    查看python关键字
    命令终端执行python
    Codeforces-462C. A Twisty Movement
    Codeforces-462A. A Compatible Pair
    Codeforces-446C. Pride
    Codeforces-Hello 2018C. Party Lemonade(贪心)
    Codeforces-33C. Wonderful Randomized Sum
    Codeforces-118D. Caesar's Legions(lazy dynamics)
    codeforces-73C. LionAge II
    Gym 101510C-Computer Science
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/3818162.html
Copyright © 2020-2023  润新知