Overview of JNDI basic operation methods for the naming and directory interface in Java

  • 2020-05-09 18:31:30
  • OfStack

General understanding of jndi:

jndi(java naming and directory Interface) it provides a set of interfaces to use the naming and directory service. It allows users to use the naming and directory services. Just like jdbc1. jndi consists of the naming service and the directory service, where the directory service contains the directory object directory object, which contains several property objects. Many operations on properties are provided.
Naming and directory services:

Naming and directory services we 1 direct in use, such as operating system file system, it provides us with the operation of the file, query, add and delete functions. The DNS service binds url to an ip address. The primary function of the naming and directory system is to bind name to objects. On top of this, it also provides more functions such as lookup,search, and the stored objects have a definite hierarchy. Using such services we can manage and manipulate objects more efficiently.
The naming service maps one name to one object. RMI Registry and CORBA Naming Service are both naming services.
The directory service also holds objects, but the directory service recognizes the relevant properties of those objects. You can use the project properties to search for directories.
In the early 1990s, the lightweight directory access protocol (LightWeightDiretoryAccessProtocol, LDAP) was developed as a standard directory protocol, and JNDI has access to LDAP.
j2se provides five extensions for jndi:

javax. naming; api provided for access to the naming service javax. naming. directory; Provides a basic interface for accessing directory services javax. naming. event; Support for event notification in naming and directory services javax. naming. ldap; ldap support package, javax. naming. spi; Provides methods for different naming and directory services to hook their implementations.

context: context is a set of name-to-object bindings (bindings), which can be understood as a hierarchy or directory, and can also include subContext at the next level. Getting initial context when using the naming and directory service is the entry point to the entire namespace operation. In the directory service it is DirContext.
JNDI(Java Naming and Directory Interface) is an application program designed to provide developers with a common, unified interface to find and access various naming and directory services, like JDBC, which are built on the abstraction layer.
Existing directories and services accessible by JNDI are:
DNS, XNam, Novell directory services, LDAP (Lightweight Directory Access Protocol lightweight directory access protocol), CORBA object services, file systems, Windows XP / 2000 / NT/Me / 9 x registry, RMI, DSML v1 & v2, NIS.
JNDI advantages:
Contains a large number of naming and directory services, using a common interface to access different kinds of services; You can connect to multiple naming or directory services simultaneously; A logical association is established that allows the name to be associated with an Java object or resource without having to direct the physical ID of the object or resource.

JNDI package:

javax.naming: naming operation; javax. naming. directory: directory operation; javax.naming.event: request event notifications in the named directory server; javax. naming. ldap: LDAP support; javax.naming.spi: allows dynamic insertion of different implementations. The naming and service capabilities of JNDI are used for enterprise-level APIs access to naming and services, such as EJBs, JMS, JDBC 2.0, and RMI on IIOP using CORBA naming services via JNDI.

JNDI and JDBC:
JNDI provides a unified way to find and access services over the network. By specifying a resource name that corresponds to a record in a database or naming service, it returns the information necessary to establish a database connection.
Code example:


try{
Context cntxt = new InitialContext();
DataSource ds = (DataSource) cntxt.lookup("jdbc/dpt");
}
catch(NamingException ne){
...
}

JNDI and JMS:
Message communication is a method used by software components or applications to communicate. JMS is an JAVA technology that allows applications to create, send, receive, and read messages.
Code example:


try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}

Access specific directories: for example, a person is an object that has several properties, such as the person's name, phone number, E-mail address, zip code, and so on. Through the getAttributes() method


Attribute attr = directory.getAttributes(personName).get("email");
String email = (String)attr.get();

Use JNDI to get the client to use the object's name or properties to find the object:


foxes = directory.search("o=Wiz,c=US", "sn=Fox", controls);

Find examples of printers by using JNDI to find objects such as printers and databases:


Printer printer = (Printer)namespace.lookup(printerName);
printer.print(document);

Browse the namespace:


NamingEnumeration list = namespace.list("o=Widget, c=US");
while (list.hasMore()) {
NameClassPair entry = (NameClassPair)list.next();
display(entry.getName(), entry.getClassName());
}
Common JNDI operations:
void bind (String sName, Object object); Binding: the process of associating a name with an object void rebind (String sName, Object object); Binding: used to bind an object to an existing name void unbind (String sName); Release: used to release objects from a directory void lookup (String sName, Object object); Lookup: returns the total number of objects in the directory void rename (String sOldName, String sNewName); Rename: the name used to modify the object name binding NamingEnumeration listBinding (String sName); Manifest: returns a manifest list of objects bound in a particular context NamingEnumeration list(String sName);

Code example: the name, class name, and binding object are retrieved.


NamingEnumeration namEnumList = ctxt.listBinding("cntxtName");
...
while ( namEnumList.hasMore() ) {
Binding bnd = (Binding) namEnumList.next();
String sObjName = bnd.getName();
String sClassName = bnd.getClassName();
SomeObject objLocal = (SomeObject) bnd.getObject();
}

Understanding the concepts of name services and directory services can help you make better use of JNDI. The Naming service             name service defines how to associate a name with an object and how to find an object by name. Typical examples are: DNS associates a domain name with IP, and a file system associates a file name with a file. In the name service, the main concepts are:
-                name (Names), the name of the actual object in the name system, such as the file name, the domain name, etc., which is used to find the associated object. Different systems have different naming conventions, such as "\" for the file system to represent the hierarchy, and ". "for DNS.
-                binding (Bindings), the association between the name and the actual object.
-                  reference and address (References References       Addresses), when an object cannot be stored directly in the name system, the reference must be used to find the actual object. In the system, the contents of saved references are called addresses. References have another use: in the name system, there is a lack of concepts like keys in relational databases. By using a reference, you can use it as an alternative to a foreign key.
-                context (Context), which is a collection of name-objects that provides the main operations for interacting with the name system, such as find, bind, and unbind. The subcontext (subcontext) is similar to the relationship between a directory and a subdirectory in a file system. The subcontext is contained in a context and is associated with the subcontext by a name in the parent context.
-                  and Namespaces                       Namespaces A namespace is a collection of names in the name system, such as the file name and directory of the file system.
The Directory service           directory service is an extension of the name service, which allows objects to contain properties in addition to associating names with objects. A directory system usually organizes data in a hierarchy. Key concepts in directory services:
-                property (Attributes), which belongs to a directory object, is a (name, value) pair, and can have multiple values.
-                                Directories and Directory Services The directory service provides directory-related services to create, delete, and modify the properties of objects stored in the directory.
-                  Searches and Search Filters A filter is an object that is similar to a lookup condition.
The basic use
 
& sup2;               register with JNDI provider
Before you can use JNDI, you need to get the provider of JNDI and register it with your system. System properties associated with JNDI are defined in javax.naming.Context. Common properties are:
-                   java. naming. factory. initial, the service provider is used to create InitialContext class name.
-                   java. naming. provider. url, used to configure the initial InitialContext url
-                   java. naming. factory. object, used to create name to - object mapping class, used for NameClassPair and References.
-                   java. naming. factory. state, used to create jndi state class
For directory services, because 1 generally requires security Settings, it is also common to use:
-                   java. naming. security. authentication, security type, three values: none, simple or strong.
-                   java. naming. security. principal, authentication information.
-                   java. naming. security. credentials, certificate information.
-                   java. naming. security. protocol, security protocol.
Register with System.setProperty. If the program does not show instructions, java will look up the jdni.properties file in classpath to complete the registration. jdni. properties example:
java.naming.factory.initial=com.codeline.db.MockInitialContextFactory
 
Connection service
After registration, the service connection can be implemented. For the name service, InitialContext is used; for the directory service, InitialDirContext is used. They implement Context and DirContext respectively, which correspond to the interfaces of the name service and directory service respectively, and are also the two most important interfaces in JNDI.
Connection name service:                          


System.setProperty(Context.INITIAL_CONTEXT_FACTORY," 
com.sun.jndi.fscontext.FSContextFactory"); 
InitialContext ctx = new InitialContext();

Connect to directory service:


 Hashtable env = new Hashtable(); 
 env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
 env.put(Context.PROVIDER_URL, "ldap://myserver.com/");
 env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
 // The login ldap server The required user name  
 env.put(Context.SECURITY_PRINCIPAL, "ldapuser"); 
 // The login ldap server Required password  
 env.put(Context.SECURITY_CREDENTIALS, "mypassword"); 
InitialDirContext ctx = new InitialDirContext(env);

 
Multiple service providers: if the application contains multiple service providers, the connection is slightly different. Take the name service


Hashtable env = new Hashtable(); 
 env.put(Context.INITIAL_CONTEXT_FACTORY, 
"com.sun.jndi.rmi.registry.RegistryContextFactory"); 
 env.put(Context.PROVIDER_URL, "rmi://myserver.com:1099"); 
 // Use different constructors  
InitialContext ctx = new InitialContext(env); 

 
To find the object
Both the name service and the directory service use lookup to find objects. In addition to using String as a parameter, lookup can also use the Name interface as a parameter.


try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}
0

If you want to get the names of all the objects in the context, return the NameClassPair list using lis. NameClassPair contains the object name and the object class name. If you want to get the actual list of object instances, you use listBindings, which returns the Binding list. Binding is a subclass of NameClassPair that contains instances of objects.
-   list


NamingEnumeration list = ctx.list("awt"); 
while (list.hasMore()) { 
 NameClassPair nc = (NameClassPair)list.next(); 
 System.out.println(nc); 
}

-   listBindings


NamingEnumeration bindings = ctx.listBindings("awt"); 
while (bindings.hasMore()) { 
 Binding bd = (Binding)bindings.next(); 
 System.out.println(bd.getName() + ": " + bd.getObject()); 
} 

 
Object binding
- use bind to add bindings


try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}
3

- modify the binding using rebind


try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}
4

- use unbind to remove the binding.


try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}
5

 
Object name
You can rename an object in context using rename


try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}
6

- get properties
The property-related interfaces are Attribute and Attributes, both in the javax.naming.directory package. The collection of properties of an object can be obtained by DirContext's getAttributes method, then the corresponding properties can be obtained by Attributes's get method, and finally the property values can be obtained by Attribute's get method.


String dn = "uid=me, dc=mycompany, dc=com, ou=customer, o=ExampleApp"; 
Context user = (Context)ctx.lookup(dn); 
// Get all the properties  
Attributes attrs = user.getAttributes(""); 
Attribute test= attrs .get("test"); 
Object testValue= test.get(); 

In the above example, all the properties of user are obtained. In the actual use, considering the influence of network bandwidth, the property list to be acquired can be set:


String reqd_attrs = new String[] { "surname", "initials","title", "rfc822mailalias"}; 
Attributes attrs = user.getAttributes("", reqd_attrs); 

 
Find and filter
Use the search method to do this.


try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}
9

 
Main filtering methods of DirContext interface:
1. Use the filter string  


String reqd_attrs = new String[] { "cn", "uid","rfc822mailalias" }; 
NamingEnumeration results = initial_ctx.search("ou=Customer, o=ExampleApp",search_attrs,reqd_attrs); 

 
2. Use SearchControls for more control


SearchControls ctrls = new SearchControls(); 
ctrls.setCountLimit(20); 
ctrls.setTimeLimit(5000); 
ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE); 
NamingEnumeration results = initial_ctx.search("cat=books,ou=Products, 
o=ExampleApp","title=*Java*",ctrls); 

Modify the properties
This is done using the modifyAttributes method of DirContext and InitialDirContext. The modification process is essentially the construction of a list of properties to be modified and then the submission using the method described above. When a property contains multiple values, the unmodified values of the property need to be included as well, otherwise the server will remove the values as no longer needed.


 public void updateAddress(String dn,String address, String country, String phone) { 
  BasicAttributes mod_attrs = new BasicAttributes(); 
  if(address != null) 
   mod_attrs.put("address", address); 
   if(country != null) 
    mod_attrs.put("c", country); 
  if(phone != null) 
    mod_attrs.put("phonenumber", phone); 
   if(mod_attrs.size() != 0) 
   initial_ctx.modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, mod_attrs); 
} 

Using ModificationItem, multiple different modification operations can also be performed once:


ModificationItem[] mod_items = new ModificationItems[2]; 
Attribute email = new BasicAttribute("rfc822mailalias", new_email); 
ModificationItem email_mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, email); 
Attribute addr = new BasicAttribute("address", address); 
ModificationItem addr_mod = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, addr); 
mod_items[0] = email_mod; 
mod_items[1] = addr_mod; 
initial_ctx.modifyAttributes(dn, mod_items);

Create context
This is done using the createSubcontext method.


 BasicAttributes attrs = new BasicAttributes(); 
attrs.put("initials", initials); 
 attrs.put("sn", surname); 
 attrs.put("rfc822mailalias", email); 
 if(address != null) 
  attrs.put("address", address); 
 if(country != null) 
  attrs.put("c", country); 
 if(phone != null) 
 attrs.put("phonenumber", phone); 
initial_ctx.createSubcontext(dn, attrs); 

 
Delete context
This is done using the destroySubcontext method.


initial_ctx.destroySubcontext(dn); 

The instance
Here is another example.

Configuration in tomcat conf/ server.xml:


<Context path="/jndi"> 
 
 <Resource name="bean/MyBeanFactory" auth="Container" 
   type="com.huawei.jndi.bean.MyBean" 
   factory="org.apache.naming.factory.BeanFactory" 
   bar="23"/> 
 
</Context> 

Above, a component is declared in tomcat, which can be obtained in the code below:


try 
{ 
 Context initContext = new InitialContext(); 
 Context envCtx = (Context) initContext.lookup("java:comp/env"); 
 MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory"); 
 System.out.println(bean.getBar()); 
} 
catch (Exception e) 
{ 
 e.printStackTrace(); 
} 

Summary: configure the jndi component in tomcat, and then get the configured component in the code.

Each WEB container JNDI implementation class is different, such as in JBOSS JNDI provide class is org jnp. interfaces. NamingContextFactory, with tomcat is different.

In this case, JNDI does much the same thing as spring does with dependency injection. But with JNDI, you can get components across applications and even across domains. Components configured on server A are available on another server B via JNDI.

spring also provides encapsulation of jndi to make it easier to use. Here is an example.


<!-- JNDI The template  --> 
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
 <property name="environment"> 
  <props> 
   <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop> 
   <prop key="java.naming.provider.url">10.137.96.212:18199</prop> 
   <prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop> 
  </props> 
 </property> 
</bean> 
 
<!--  Create a connection factory  --> 
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
 <property name="jndiTemplate" ref="jndiTemplate" /> 
 <property name="jndiName" value="TopicConnectionFactory" /> 
</bean> 

Declare JndiTemplate first, configure the target address, JNDI service provider class. Then, with JndiObjectFactoryBean, you can easily get the JNDI component and do the type conversion.


Related articles: