CONTENTS | PREV | NEXT |
This section outlines a few application scenarios to help illustrate the capabilities enabled by JNDI.
The examples below are not meant to be prescriptive. There are often several ways to solve a problem, and JNDI is designed with flexibility in mind.
In secure systems, a user must authenticate himself to the computer, network, or service that he wishes to access. For example, logging into Unix requires the user to supply a password. Similarly, use of SSL requires that the user supply his X.509 certificate. Such authentication information can be stored as attributes associated with each user in the directory. The system performing the authentication would look up the attribute (for example, "password") of the user and verify the authenticity using the information supplied by the user.
DirContext ctx = new InitialDirContext(); Attribute attr = ctx.getAttributes(userName).get("password"); String password = (String)attr.get();
A useful feature of an electronic mail system is a directory service that provides a mapping between users and email addresses. This allows mail users to search for the email address of a particular user. This is analogous to searching for an individual's telephone number in the phone book in order to dial his phone number. For example, when I want to send mail to John Smith in my department, I search for "John Smith" in the directory using a "search" widget in the mail application. The widget returns to me five entries of John Smith, from which I select the one that is in a building on my site and use the email address attribute associated with that entry.
NamingEnumeration matches = deptCtx.search("user", new BasicAttributes("name", "John Smith")); // use matches to construct a selectable list for end-user while (matches.hasMore()) { SearchResult item = (SearchResult) matches.next(); Attributes info = item.getAttributes(); /* display attributes */ ... }
The directory could also be used by users to set up personalized address books. For example, once I have located John Smith's email address, I might not want to search the directory again each time I send him mail. Instead, I can create a personal subtree in the directory in which I maintain entries that I frequently use, possibly by creating links to the existing entries.
Database applications can use the directory to locate database servers. For example, a financial application needs to get the stock quotes from a stock quote server using JDBC. This application can enable the user to select the stock quote server based on specification of some attributes (such as coverage of which markets and frequency of quote updates). The application searches the directory for quote servers that meet these attributes, and then retrieves the "location" attribute (a JDBC URL) of the selected quote server and connects to it.
NamingEnumeration matches = ctx.search("service/stockQuotes", "(&(market=NASDAQ)(updateFreqency<=300))", searchctls); while (matches.hasMore()) { SearchResult item = (SearchResult)matches.next(); Attribute location = item.getAttributes().get("location"); ... }
When using almost any kind of interactive application that asks a user to input names, the user's job is made easier if a namespace browser is available to him. The browser can either be built into the application and tailored to suit that application in particular, or it can be more general-purpose such as a typical web browser.
A very simple example of
a JNDI browser allows a user to "walk" through a
namespace, viewing the atomic names at each step along the way. The
browser prints a "*" to highlight the name of each
Context
, thus telling the user where he can go next.
1
// Start at the top -- the initial context. Context ctx = new InitialContext(); while (ctx != null) { // display one level NamingEnumeration items = ctx.list(); while (items.hasMoreElements()) { NameClassPair item = (NameClassPair)items.next(); if (isContext(item.getClassName())) { System.out.print("*"); } else { System.out.print(" "); } System.out.println(" " + item.getName()); } // Take the next step down into the namespace. String target = input.readLine(); try { ctx = (Context)ctx.lookup(target); } catch (NamingException e) { // handle error } catch (ClassCastException e) { // not a context; cannot traverse } }
An important function of a printing service is to provide a means for its human users to easily discover and select printers in the network. An application that needs to print, or the machine on which it runs, should not have to be configured each time a new printer is added to the network. The scope of network access to printers may range from a workgroup to global. The printing service can use the directory to provide this capability.
Assume that printers are
represented by a Printer
interface. One of the methods
in it could be print()
which, when given an
InputStream
, will read data from
InputStream
and print it on the printer represented by
this instance of Printer.
interface Printer { void print(InputStream data) throws PrinterException; ... }
A user selects a printer
using a logical printer name, either explicitly or through default
settings. For example, the user might have specified a default
printer to use for all his applications, which is overridden only
when he explicitly specifies another printer to use. The
application that is accepting the print request takes the printer
name and looks it up in the directory service. The application
expects to receive as the result an object that implements the
Printer
interface.
void myAppPrint(String printerName, String fileName) throws IOException { try { DirContext ctx = new InitialDirContext(); Printer prt = (Printer) ctx.lookup(printerName); prt.print(new FileInputStream(fileName)); } catch (NamingException e){ System.err.println("Could not locate printer: " + e); } catch (ClassCastException e) { System.err.println(printerName + "does not name a printer"); } }
Selecting a printer by
explicitly giving its name is but one way of identifying a printer.
The user can also use the directory to see the different printers
available (browsing), or to search for printers with particular
attributes. For example the user can ask the directory to list all
the printers on the second floor of building 5 in the Mountain View
campus, or search for all color laser printers with 600dpi
resolution. From the application's perspective, just as
lookup()
returned a Printer
object, the
list and search operations also provide the same capability of
returning Printer
objects that the application could
use to submit print requests.