此Java教程是针对JDK 8编写的。本页面描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言更改以获取Java SE 9及后续版本中更新的语言功能摘要。
请参阅JDK发行说明以了解所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息。
创建连接的方式有几种。最常见的方式是通过创建初始上下文来实现。当您使用LDAP服务提供程序创建InitialContext、InitialDirContext或InitialLdapContext时,会立即与在Context.PROVIDER_URL属性中指定的目标LDAP服务器建立连接。每次创建初始上下文时,都会创建一个新的LDAP连接。有关如何更改此行为的信息,请参阅池化部分。
如果属性值包含多个URL,则会逐个尝试每个URL,直到成功创建一个连接为止。然后,属性值会更新为成功的URL。有关使用URL列表创建初始上下文的示例,请参阅JNDI教程。
还有三种直接创建连接的方式。
Context 实例和从一个 Context 实例派生的 NamingEnumeration 在更改一个 Context 实例之前共享同一个连接,直到共享不再可能。例如,如果你调用了 Context.lookup()、Context.listBindings() 或者 DirContext.search() 从初始上下文中获取其他 Context 实例,那么所有这些 Context 实例将共享同一个连接。
这里有一个示例
。
// 创建初始上下文 DirContext ctx = new InitialDirContext(env); // 获取相同上下文的副本 Context ctx2 = (Context)ctx.lookup(""); // 获取子上下文 Context ctx3 = (Context) ctx.lookup("ou=NewHires");
在这个示例中,ctx、ctx2 和 ctx3 将共享同一个连接。
无论 Context 实例是如何创建的,共享都是可行的。例如,通过跟随引荐获得的 Context 实例将与引荐共享同一个连接。
当你更改与连接相关的 Context 实例的环境属性,例如用户的主体名称或凭据,做出这些更改的 Context 实例将获得自己的连接(如果连接是共享的)。将来从此 Context 实例派生的 Context 实例将共享这个新连接。之前共享旧连接的 Context 实例不受影响(也就是说,它们继续使用旧连接)。
这里有一个示例
,使用了两个连接。
// 创建初始上下文(第一个连接) DirContext ctx = new InitialDirContext(env); // 获取相同上下文的副本 DirContext ctx2 = (DirContext)ctx.lookup(""); // 在 ctx2 中更改身份验证属性 ctx2.addToEnvironment(Context.SECURITY_PRINCIPAL, "cn=C. User, ou=NewHires, o=JNDITutorial"); ctx2.addToEnvironment(Context.SECURITY_CREDENTIALS, "mysecret"); // ctx2 上的方法将使用新连接 System.out.println(ctx2.getAttributes("ou=NewHires"));
ctx2最初与ctx共享同一个连接。但是当它的principal和password属性被修改后,它就不能再使用ctx的连接。LDAP提供程序将自动为ctx2创建一个新的连接。
同样地,如果您使用LdapContext.reconnect()来更改Context实例的连接控制,如果连接正在共享,Context实例将获得自己的连接。
如果Context实例的连接没有被共享(即,没有派生出任何Context),那么对其环境或连接控制的更改将不会导致创建新的连接。相反,任何与连接相关的更改都将应用于现有的连接。
并非所有的连接创建都是成功的。如果LDAP提供程序在一定的超时时间内无法建立连接,它将中止连接尝试。默认情况下,这个超时时间是网络(TCP)超时值,大约几分钟。要更改超时时间,您可以使用"com.sun.jndi.ldap.connect.timeout"环境属性。该属性的值是表示连接超时的整数的字符串表示形式,单位是毫秒。
这里有一个示例
。
// 设置用于创建初始上下文的环境 Hashtable env = new Hashtable(11); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial"); // 指定超时为5秒 env.put("com.sun.jndi.ldap.connect.timeout", "5000"); // 创建初始上下文 DirContext ctx = new InitialDirContext(env); // 使用ctx进行一些有用的操作
在这个例子中,如果在5秒内无法创建连接,将抛出异常。
如果Context.PROVIDER_URL属性包含多个URL,提供程序将为每个URL使用超时时间。例如,如果有3个URL并且超时已指定为5秒,则提供程序将最多等待15秒。
有关此属性如何影响连接池的信息,请参阅连接池部分。