![]() ![]() ![]() ![]() |
Controls and Extensions |
A response control allows a server to send more information to the client than is allowed by the operation's response. There need not be a one-to-one mapping between request controls and response controls. That is, a server can accompany any response with response controls--they need not be in response to any client-initiated request control.Because an LDAP server might send response controls with any response, you might be able to collect response controls after any context method invocation. However, realistically, you would only check for response controls if you were expecting them.
The LdapContext.getResponseControls()
method is used to retrieve a context's response controls. Each time a method that communicates with the server is invoked on a context, the LDAP service provider clears any previously collected response controls and collects all response controls resulting from the current method invocation. For example, the following code fragment examines the response controls after a Context.lookup()
call:
If you invoke two context methods and then use getResponseControls(), you will only get the response controls generated by the most recent context method.// Perform lookup Object answer = ctx.lookup("ou=People"); // Retrieve the response controls Control[] respCtls = ctx.getResponseControls();Enumerations
Methods such as Context.listand DirContext.search
return NamingEnumeration
. Each member of a NamingEnumeration might have response controls. A member that has response controls implements the HasControls
interface. Here is an example that shows you how to retrieve the response controls from each member of a NamingEnumeration generated by a search() method:
This example defines a method, printControls() that prints out a Control// Perform search NamingEnumeration answer = ctx.search("ou=People", "(cn=*)", null); // examine the response controls (if any) printControls("After search", ctx.getResponseControls()); // Enumerate answers while (answer.hasMore()) { SearchResult si = (SearchResult)answer.next(); System.out.println(si); // examine the response controls (if any) if (si instanceof HasControls) { printControls(si.getName(), ((HasControls)si).getControls()); } } // examine the response controls (if any) printControls("After enumeration", ctx.getResponseControls());array. It first performs a search, examines the response controls after the search, and then enumerates the results of the search. For each member of the enumeration, it checks whether the member implements the HasControls interface and if so, displays the response controls associated with the member. After the enumeration has completed, it checks for response controls of the context by using ctx.getResponseControls().
Exceptions
If a context method throws an exception and the LDAP server had sent response controls with the error response that generated the exception, you can retrieve the response controls using ctx.getResponseControls(). Here is an example:try { // Perform lookup Object answer = ctx.lookup("ou=People"); // Retrieve the response controls Control[] respCtls = ctx.getResponseControls(); // Display respCtls } catch (NamingException e) { // Retrieve the response controls Control[] respCtls = ctx.getResponseControls(); // Handle exception }Implementations
The Control interface is generic for all request and response controls. Typically, you would be dealing implementation classes that implement this interface rather than directly using the methods in this interface. Such implementation classes typically have type-friendly and accessor methods. After getting the response controls by using getResponseControls(), you can cast the control to its most derived class and use the class-specific accessor methods.For example, Sun provides classes that implement some popular controls, such as the server-side sorting control. The server-side sorting response control is represented by the SortResponseControl class. You can use the following code to access information about the server-side sorting response control:
In order to do this casting and use specific control classes, you must have some expectation of receiving such a control from the server and have made the control classes available to your program. If either of these is lacking, you can only use the methods in the Control interface to determine the identity of the control and to decode its contents.if (controls[i] instanceof SortResponseControl) { SortResponseControl src = (SortResponseControl)controls[i]; if (src.isSorted()) { // result was sorted ... } } ...Response Control Factories
The JNDI allows an application to use control implementation classes that are produced by any vendor. To help service providers achieve this goal, the JNDI provides a method ControlFactory.getControlInstance(Control, Context, Hashtable)for service providers to use to transform (that is, to narrow) generic controls received from an LDAP server into control classes made available to the application.
A control factory is an entity that narrows a control. It is represented by the abstract class, ControlFactory
. A control received from an LDAP server starts out life as a Control instance. The LDAP service provider uses the getControlInstance() method to narrow the control instance into a more type-specific one. This method searches the list of ControlFactory class implementations specified in the LdapContext.CONTROL_FACTORIES
("java.naming.factory.control") environment property for a class that can narrow the control.
For example, if an application uses an LDAP server that returns a special response control, the application can define a response control factory to parse the control and provide type-friendly accessor methods. Here is an example of a response control factory:
The factory class must have a public constructor that accepts no arguments. It must also provide an implementation for the abstract method ControlFactory.getControlInstance(Control)public class SampleResponseControlFactory extends ControlFactory { public SampleResponseControlFactory() { } public Control getControlInstance(Control ctl) throws NamingException { String id = ctl.getID(); // See if it's one of ours if (id.equals(SampleResponseControl.OID)) { return new SampleResponseControl(id, ctl.isCritical(), ctl.getEncodedValue()); } // Not one of ours; return null and let someone else try return null; } }. This method should check whether the input control is one that it can narrow. If so, it should process the control and return an object of a more type-specific class. If it cannot narrow the control, it should return null so that other factories may be tried.
![]() ![]() ![]() ![]() |
Controls and Extensions |