JNDI(Java Naming and Directory Interface, Java命名和目錄接口),說白了,就是經過配置一些xml文件,方便用戶直接調用API使用某些通用的資源。html
舉個簡單的例子,若是在tomcat中部署了不少應用,應用都須要使用同一個數據庫,若是每一個應用都在代碼中配置數據庫的鏈接,確定是很麻煩的。java
因此經過JNDI就能夠簡單的經過 InitialContext 獲取到統一配置的資源,簡化代碼的編寫。web
本篇主要內容按照上面來說解,其中樣例部分主要說明一下通用javabeans和userdatabase,javamail不多使用,JDBC又很大衆化,網上不少資料,能夠參考 JNDI配置數據源,就不作重複工做了。數據庫
爲了不篇幅過長,自定義JNDI則留到後面再說。express
這裏說明的內容,不是每次編碼必須的步驟,只是先說明一下都有哪些地方涉及到配置。apache
web.xmltomcat
這部份內容配置資源引用,舉個例子:session
<resource-env-ref> <description> 資源配置說明 </description> <resource-env-ref-name> bean/MyBeanFactory </resource-env-ref-name> <resource-env-ref-type> com.mycompany.MyBean </resource-env-ref-type> </resource-env-ref>
在web.xml中能夠配置三種形式的資源:app
<env-entry> 用於配置一些應用程序的變量,好比參考 tomcat下部署solr。less
<resource-ref> 資源引用,一般是一個對象工廠資源,好比典型的JDBC數據源。
<resource-env-ref> 資源環境引用,他是servlet2.4中新引入的特性,在resource-ref的基礎上,能夠更簡單方便的配置信息而不用通過身份驗證,好比簡單的javabean。
context.xml
這部分定義其引用的資源工廠以及一些必要的額外信息,好比:
<Context ...> ... <Resource name="bean/MyBeanFactory" auth="Container" type="com.mycompany.MyBean" factory="org.apache.naming.factory.BeanFactory" bar="23"/> ... </Context>
這裏須要注意的是,<context>標籤有三種配置位置:
1 在conf/server.xml中;
2 在conf/context.xml中;
3 在/webapps/xxx/WEB-INF/context.xml;
這三種的區別是,server.xml與context.xml相似都是全部應用通用的,可是context.xml只是把它分離出來單獨造成了一個文件而已。在WEB-INF/下的context.xml則是應用本身的,因此若是不想把某些信息公開,放在這裏就能夠了。
在<context>中能夠配置以下的標籤:
<Environment> 配置一些鍵值對變量,相似於<env-entry>
<Resource> 配置一些資源的類型和變量信息,相似於<resouce-ref>
<ResourceLink> 指定資源連接到全局上下文中的配置,好比在server.xml中配置了全局的一個標籤,這裏能夠直接引入該標籤名字。
<Transaction> 添加工廠資源實例
server.xml
這個文件中能夠配置<context>標籤,前面說過了;還能夠配置全局JNDI資源,好比默認的tomcat就配置了一個userdatabase的資源
<GlobalNamingResources> <!-- Editable user database that can also be used by UserDatabaseRealm to authenticate users --> <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/> </GlobalNamingResources>
它就是一個全局的配置。
配置好相應的xml文件,就能夠在代碼中直接經過建立Context實例,例如在配置數據源中:
Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env");
//上面寫法都是不變的,下面這行中lookup中的字符串就是配置的JNDI名稱,
//好比context中的<resource name="xxx">或者web.xml中的<resource-env-ref-name> DataSource ds = (DataSource)envCtx.lookup("jdbc/EmployeeDB"); Connection conn = ds.getConnection(); ... use this connection to access the database ... conn.close();
最後參考幾個樣例,瞭解一下編碼細節。
1 通用JavaBean資源
首先,建立本身的javabean,並配置其構造方法設置初始化值。
package com.mycompany; public class MyBean { //配置變量foo private String foo = "xingoo"; public String getFoo() { return (this.foo); } public void setFoo(String foo) { this.foo = foo; } //配置變量bar private int bar = 0; public int getBar() { return (this.bar); } public void setBar(int bar) { this.bar = bar; } }
而後,配置web.xml中資源引用
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>JSPTest</display-name> <resource-env-ref> <description> javaBean測試 </description> <resource-env-ref-name> bean/MyBeanFactory </resource-env-ref-name> <resource-env-ref-type> com.mycompany.MyBean </resource-env-ref-type> </resource-env-ref> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
接下來,在tomcat conf/context.xml中配置工廠資源引用,並設置初始化的值
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --><!-- The contents of this file will be loaded for each web application --><Context> <!-- Default set of monitored resources --> <WatchedResource>WEB-INF/web.xml</WatchedResource> <!-- Uncomment this to disable session persistence across Tomcat restarts --> <!-- <Manager pathname="" /> --> <!-- Uncomment this to enable Comet connection tacking (provides events on session expiration as well as webapp lifecycle) --> <!-- <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" /> --> <Resource name="bean/MyBeanFactory" auth="Container" type="com.mycompany.MyBean" factory="org.apache.naming.factory.BeanFactory" bar="23"/> </Context>
最後在JSP中調用lookup方法,得到實例。
<%@ page language="java" contentType="text/html; charset=utf-8" import="java.net.*,javax.naming.*,com.mycompany.*" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>test JNDI</title> </head> <body> <h1>test JNDI</h1> <hr> <% Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory"); %> foo:<%=bean.getFoo() %><br> bar:<%=bean.getBar() %> </body> </html>
運行效果:
因爲foo沒有在<Resouce>標籤中設置值,所以讀取的仍是默認的值,而bar則爲設置的值。
2 Userdatabase使用
userdatabase即用戶數據庫,主要用於配置用戶信息,以供某些應用進行受權驗證。
關於其餘的配置好比web.xml的Realm配置這裏就很少說了,看看server.xml中如何設置全局資源引用:
<?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="SHUTDOWN"> ... <GlobalNamingResources> <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/> </GlobalNamingResources> <Service name="Catalina"> ... <Engine defaultHost="localhost" name="Catalina"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> ... </Engine> </Service> </Server>
其中<GlobalNamingResources>配置了全局命名資源UserDatabase,後面再進行Realm域管理時,直接經過resourceName連接到該資源。
3 JNDI數據源配置
這部分就很少說了,參考下面的JNDI配置數據源便可。
【1】tomcat 6 JNDI resource : http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html
【2】經過JNDI配置數據源:http://www.blogjava.net/supercrsky/articles/174931.html