ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Developing A White Pages Service with LDAP and JNDI
Pages: 1, 2, 3, 4, 5, 6, 7

Accessing A Naming Service

When accessing a naming service, you first need a service provider. The first thing to do is to get the initial context, which is the starting position into the namespace. You acquire the initial context before you do any other operation. This is because all operations on naming and directory services are performed relative to some context. If you specify that your initial context when accessing a filesystem is the /usr/local directory when you call the list() method, then it's the contents of the /usr/local directory that will be returned. You can think of the initial context as the application default directory.

To obtain the initial context, you call the InitialContext() constructor, passing all the necessary environment information in a Hashtable object:

Hashtable env = new Hashtable();

Into the Hashtable, you then put the service provider. For example, if you are using the filesystem service provider from Sun, this is the line of code you need.

env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");

The filesystem service provider can be downloaded here.

If you are using a different service provider, replace put()'s second argument.

Another important environment property that you need to get the initial context is the PROVIDER_URL. This property is assigned the location of the initial context. This could be a URL on the Internet or it could just be a directory in a file system. For instance, if you decide that your initial context when accessing a Unix filesystem is the /usr/local directory, then you need the following line of code.

env.put(Context.PROVIDER_URL, "file:/usr/local");

Or, on a Windows system, if you want the C:\data directory to be the initial context, your code would look like the following.

env.put(Context.PROVIDER_URL, "file:C:\\data");

And, optionally, you can also put the user credentials such as the username and password.

env.put(Context.SECURITY_PRINCIPAL, "james"); 
env.put(Context.SECURITY_CREDENTIALS, "secret");

Having the environment information ready, you can now create the initial context.

Context ctx = new InitialContext(env);

If the object is created successfully, you can use the resulting Context object to access the naming service. The lookup method of the Context interface can be used to retrieve an object by passing its name.

Object obj = ctx.lookup("info.txt");

For example, the following code prepares an environment Hashtable object, creates an initial context, and retrieves the info.txt file.

import java.util.Hashtable;
import javax.naming.*;
import java.io.File;

public class Naming {
  public static void main(String[] args) {

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
      "com.sun.jndi.fscontext.RefFSContextFactory");
    env.put(Context.PROVIDER_URL,  
      "file:C:\\123data\\MyArticles\\WhitePagesWithLDAP");
    env.put(Context.SECURITY_PRINCIPAL, "james");
    env.put(Context.SECURITY_CREDENTIALS, "secret");

    try {
      Context ctx = new InitialContext(env);
      File f = (File)ctx.lookup("info.txt");
    }
    catch (NamingException e) {
      System.out.println(e.toString());
    }
  }
}

The Object object from the lookup method is cast to a File object. If the object is a Printer, you can do something similar:

  Printer printer = (Printer) ctx.lookup("BigMomma");
  printer.print(report);

Some of the code is in a try-catch wrapper because many methods in the JNDI packages can throw a NamingException.

Other useful methods of the Context interface include the following.

  • bind -- Binds an object to a name. After the binding, you can retrieve the object by looking up the name.
  • rebind -- Adds or replaces a binding. If the name is already bound to an object, it will be unbound and bound with the new object specified as the argument of this method.
  • unbind -- Removes a binding.
  • list -- Enumerates the names bound in the named context, along with the class names of objects bound to them.

Every naming method in the Context interface has two overloads: one that accepts a Name argument and one that accepts a java.lang.String name. Name is an interface that represents a generic name; an ordered sequence of zero or more components.

The overloads that accept Name are useful for applications that need to manipulate names, that is, composing them, comparing components, and so on.

A java.lang.String name argument represents a composite name. The overloads that accept java.lang.String names are likely to be more useful for simple applications, such as those that read in a name and look up the corresponding object.

Accessing A Directory Service

When you access a directory service, there are several initial steps to perform. The first is to prepare an environment Hashtable object to get the initial context.

Hashtable env = new Hashtable();

One of the environment properties you need to set is the INITIAL_CONTEXT_FACTORY. For example, if you are accessing an LDAP service, you can use the service provider from Sun. The code would then look like the following.

env.put(Context.INITIAL_CONTEXT_FACTORY,
  "com.sun.jndi.ldap.LdapCtxFactory");

If you are using a service provider from another vendor, just replace the second argument to put(). Next, you supply the location of the service. For example, the following specifies a location of an LDAP server at ldap://sendal.jepit.edu.au:389 (389 is the default port for the LDAP service).

env.put(Context.PROVIDER_URL, 
  "ldap://sendal.jepit.usyd.edu.au:389");

You can then acquire an initial context by passing the environment Hashtable. However, unlike accessing a naming system, you use the DirContext interface instead of the Context interface.

DirContext ctx = new InitialDirContext(env);

Having a DirContext object, you can access the directory service using the methods of the DirContext interface; the important methods of which include getAttributes, getSchema and search.

  • getAttributes -- Returns the attributes of an object in the directory. For this method to work, you need to pass the name of the object for which you want the attributes. If you have an object whose name is "cn=boni, ou=person", you can retrieve the object's attributes using the following line of code.

    Attributes attr = ctx.getAttributes("cn=boni, ou=person");
  • getSchema -- Retrieves the schema associated with the named object.

  • search -- Search for entries in a named context or object. The search must satisfy a given search filter. The syntax of one of the many search methods is as follows.

    public NamingEnumeration search(String name, String filter,
      SearchControls cons) throws NamingException

    The parameters are given below.

    • name -- The name of the context or object to search.
    • filter -- The filter expression to use for the search; may not be null
    • cons -- These control the search. If null, the default search controls are used (equivalent to (new SearchControls())).

    You can create a SearchControls object by using the following code.

    SearchControls constraints = new SearchControls();
    constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

Pages: 1, 2, 3, 4, 5, 6, 7

Next Pagearrow