Module  java.naming

Package javax.naming.ldap

提供对LDAPv3扩展操作和控件的支持。

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

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

扩展操作

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

应用程序通常不直接处理这些接口。 相反,它处理实现这些接口的类。 应用程序将这些类作为通过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;
    }
}

控制

此包定义了用于表示LDAPv3控件的接口Control 它可以是发送到LDAP服务器( 请求控制 )或由LDAP服务器返回的控件( 响应控件 )的控件 与扩展请求和响应不同,请求控件和响应控件之间不一定要配对。 您可以发送请求控制,并且不需要响应控制,或接收响应控制,而不发送任何请求控件。

应用程序通常不直接处理此接口。 而是处理实现此接口的类。 应用程序获取控制类,作为通过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提供了一种用于获取使用LDAP操作发送的响应控件的方法( getResponseControls() ),而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 documentation中找到。
从以下版本开始:
1.3