模块 java.naming

包 javax.naming.ldap


javax.naming.ldap
提供对 LDAPv3 扩展操作和控制的支持。

这个包扩展了 Java 命名和目录接口 (JNDI) 的目录操作。 JNDI 为用 Java 编程语言编写的应用程序提供命名和目录功能。它旨在独立于任何特定的命名或目录服务实现。因此,可以以通用方式访问各种服务——新的、新兴的和已经部署的服务。

此软件包适用于处理 LDAPv3 扩展操作和控制的应用程序和服务提供商,如 RFC 2251 所定义。此包中的核心接口是 LdapContext ,它在上下文中定义了用于执行扩展操作和处理控件的方法。

扩展操作

该包定义接口 ExtendedRequest 来表示扩展操作的参数,以及接口 ExtendedResponse 来表示扩展操作的结果。扩展响应总是与扩展请求配对,但反之不一定。也就是说,您可以有一个没有相应扩展响应的扩展请求。

应用程序通常不直接处理这些接口。相反,它处理implement这些接口的类。应用程序获取这些类作为通过 IETF 标准化的扩展操作的一部分,或者从目录供应商处获取特定于供应商的扩展操作。请求类应该具有以类型安全和用户友好的方式接受参数的构造函数,而响应类应该具有以类型安全和用户友好的方式获取响应数据的访问方法。在内部,请求/响应类处理编码和解码 BER 值。

例如,假设 LDAP 服务支持“获取时间”扩展操作。它将提供诸如 GetTimeRequestGetTimeResponse 之类的类,以便应用程序可以使用此功能。应用程序将按如下方式使用这些类:

GetTimeResponse resp =
  (GetTimeResponse) ectx.extendedOperation(new GetTimeRequest());
long time = resp.getTime();

GetTimeRequestGetTimeResponse 类可能定义如下:

public class GetTimeRequest implements ExtendedRequest {
  // User-friendly constructor 
  public GetTimeRequest() {
  };

  // Methods used by service providers
  public String getID() {
    return GETTIME_REQ_OID;
  }
  public byte[] getEncodedValue() {
    return null; // no value needed for get time request
  }
  public ExtendedResponse createExtendedResponse(
    String id, byte[] berValue, int offset, int length) throws NamingException {
    return new GetTimeResponse(id, berValue, offset, length);
  }
}
public class GetTimeResponse() implements ExtendedResponse {
  long time;
  // called by GetTimeRequest.createExtendedResponse()
  public GetTimeResponse(String id, byte[] berValue, int offset, int length)
    throws NamingException {
    // check validity of id
    long time = ... // decode berValue to get time
  }

  // Type-safe and User-friendly methods
  public java.util.Date getDate() { return new java.util.Date(time); }
  public long getTime() { return time; }

  // Low level methods
  public byte[] getEncodedValue() {
    return // berValue saved;
  }
  public String getID() {
    return GETTIME_RESP_OID;
  }
}

控件

该包定义接口 Control 来表示 LDAPv3 控件。它可以是发送到 LDAP 服务的控件 (request control) 或 LDAP 服务返回的控件 (response control)。与扩展请求和响应不同,请求控件和响应控件之间不一定有任何配对。您可以发送请求控制并且期望没有响应控制返回,或者接收响应控制而不发送任何请求控制。

应用程序通常不直接处理此接口。相反,它处理implement这个接口的类。应用程序获取控件类作为通过 IETF 标准化的控件库的一部分,或者从目录供应商处获取特定于供应商的控件。请求控制类应该具有以类型安全和用户友好的方式接受参数的构造函数,而响应控制类应该具有以类型安全和用户友好的方式获取响应数据的访问方法。在内部,请求/响应控制类处理编码和解码 BER 值。

例如,假设 LDAP 服务支持“签名结果”请求控件,当它与请求一起发送时,要求服务对操作结果进行数字签名。它将提供一个类 SignedResultsControl 以便应用程序可以使用此功能。应用程序将按如下方式使用此类:

Control[] reqCtls = new Control[] {new SignedResultsControl(Control.CRITICAL)};
ectx.setRequestControls(reqCtls);
NamingEnumeration enum = ectx.search(...);
SignedResultsControl 类可能定义如下:
public class SignedResultsControl implements Control {
  // User-friendly constructor 
  public SignedResultsControl(boolean criticality) {
    // assemble the components of the request control
  };

  // Methods used by service providers
  public String getID() {
    return // control's object identifier
  }
  public byte[] getEncodedValue() {
    return // ASN.1 BER encoded control value
  }
  ...
}

当服务提供者收到响应控制时,它使用 ControlFactory 类来生成实现 Control 接口的特定类。

LDAP 服务可以通过 LDAP 操作和枚举结果(例如列表或搜索操作返回的结果)发回响应控制。 LdapContext 提供了一种方法 (getResponseControls() ) 用于获取与 LDAP 操作一起发送的响应控件,而 HasControls 接口用于检索与枚举结果关联的响应控件。

例如,假设 LDAP 服务发回“更改 ID”控件以响应成功的修改。它会提供一个类 ChangeIDControl 以便应用程序可以使用此功能。应用程序将执行更新,然后尝试获取更改 ID。

// Perform update
Context ctx = ectx.createSubsubcontext("cn=newobj");

// Get response controls
Control[] respCtls = ectx.getResponseControls();
if (respCtls != null) {
  // Find the one we want
  for (int i = 0; i < respCtls; i++) {
    if(respCtls[i] instanceof ChangeIDControl) {
      ChangeIDControl cctl = (ChangeIDControl)respCtls[i];
      System.out.println(cctl.getChangeID());
    }
  }
}
供应商可能会提供以下 ChangeIDControlVendorXControlFactory 类。当提供者从 LDAP 服务接收到响应控制时,服务提供者将使用 VendorXControlFactory
public class ChangeIDControl implements Control {
  long id;

  // Constructor used by ControlFactory
  public ChangeIDControl(String OID, byte[] berVal) throws NamingException {
    // check validity of OID
    id = // extract change ID from berVal
  };

  // Type-safe and User-friendly method
  public long getChangeID() {
    return id;
  }

  // Low-level methods
  public String getID() {
    return CHANGEID_OID;
  }
  public byte[] getEncodedValue() {
    return // original berVal
  }
  ...
}
public class VendorXControlFactory extends ControlFactory {
  public VendorXControlFactory () {
  }

  public Control getControlInstance(Control orig) throws NamingException {
    if (isOneOfMyControls(orig.getID())) {
      ...

      // determine which of ours it is and call its constructor
      return (new ChangeIDControl(orig.getID(), orig.getEncodedValue()));
    }
    return null; // not one of ours
  }
}

包装规格

JNDI API 规范和相关文档可以在 JNDI 文档 中找到。
自从:
1.3