JNDI 笔记(一) 概述

很多地方都会用到JNDI,一大堆的缩写加上一大堆不清不楚的概念描述,使得在看到的时候都不认识,更不要说使用了。

JNDI,Java Naming Directory Interface,J2EE的标准之一,所有的J2EE容器都必须提供一个JNDI的服务,但是,我一直都没用过,至少是没有刻意地去用过。因为,我也 曾经把数据源配置在Tomcat的JNDI服务中,但那时,我也只是刚刚涉足JAVA,有人告诉我应该这么干而已。后来,我开始使用自定义的数据库连接配 置文件,就再也没有跟JNDI打过交道了,直到今天。


现在之所以又想看一下,只是因为觉得这是J2EE的重要标准之一,如果不懂得的话,似乎有点说不过去。


JNDI
的主要功能可以这样描述,它使用一张哈希表存储对象(大多数的J2EE容器也的确是这样做的),然后,开发人员可以使用键值——也就是一个字符串——来获
取这个对象。这里就包括取JNDI的两个最主要操作,bind和lookup。bind操作负责往哈希表里存对象,存对象的时候要定义好对象的键值字符
串,lookup则根据这个键值字符串往外取对象。


JNDI的命称可能会让人产生混淆,似乎觉得这是一个用来操作目录的,事实上,我更愿
意把这个目录理解成为JNDI存放对象时使用的格式,也就是说,JNDI以目录的方式存储对象的属性。例如,用户通过JNDI存储一个汽车对象,那么,汽
车就是根目录,汽车的轮子、引擎之类的子对象就算是子目录,而属性,比如说汽车的牌子、重量之类,就算是汽车目录下的文件。


JNDI的功能既然就是根据一个字符串键值就可以取得一个想要得到的对象,我一开始就觉得这不是跟COM或CORBA一样吗?SUN也是有野心的企业啊,JNDI应该就是它要努力推行的JAVA下的分布式开发的标准吧。


JNDI
的出现应该就是为了分步式开发服务的,有人负责开发这种分布式对象,有人只需要使用这些分布式对象就可以了,这两组人不必属于同一个公司,而且这种开发通
常应该是不并行的,也不必是会了同一个项目服务。就如果数据源对象,它放在JNDI中,只要想要用的人,直接通过JNDI服务取来用就可以了,至于当初是
谁把它放进JNDI中的,还是不用操这份心了吧。而我一直没有使用JNDI,也就是这个原因,项目中的所有对象都在我控制之下,我不去使用别人的对象,也
没打算把我的对象贡献出来给别人使用,那自然也就没必要去跟JNDI打交道。我觉得是否使用JNDI,这应该是关键原因,至于什么方便性、安全性之类的考
虑,应该不是JNDI的主要目的,就如同你可以用JAVA来做网站,但JAVA并不是专门用来做网站的。


可能有人觉得这种功能跟IoC也
很象,这个我倒不觉得,虽然对于对象的使用人员来说的确是这种感觉,且不说IoC需要为对象定义接口,而JNDI并无此限制,先说这里有一个使用环境问
题,我觉得IoC是用来解决并行开发问题的,也就是说IoC主要是用于明确设计人员与实现/使用人员的分工,无论是设计的,还是使用的,通常是一个项目组
里的人,使用IoC,可以使得设计人员专注于设计,加快设计速度。因此,IoC的用途要比JNDI广泛的多,现在大型系统中,不使用IoC的,几稀矣。

JNDI 笔记(二) J2EE下使用JNDI

在J2EE环境下使用JNDI是非常简单的事,因为所有的J2EE容器都要实现JNDI服务,所以,在J2EE环境下使用JNDI,与使用
Hashtable也没有什么太大区别。只有一点限制,那就是绑定对象时,对象所属的类必须实现java.io.Serializable接口,这一点也
实在一点也不困难,几乎所有用到的Java类都实现了这个接口,对于自定义的类,在接口实现列表里把这个接口加进去也就是了。

下面,我将演示一下如何在J2EE环境下使用JNDI,为了保证代码的通用性,我不使用struts之类的框架,而是直接使用标准JSP和Servlet实现。我将该项目的名称定为jndi_test

要使用JNDI,需要先到SUN的网站上去下载jndi.jar。

 2.1 JSP

本项目包括5个JSP,功能说明如下:

  • index.jsp:首页
  • bind.jsp:用于在JNDI中绑定对象
  • bind_result.jsp:绑定对象后的返回页面
  • lookup.jsp:用于在JNDI中检索对象
  • lookup_result.jsp:用于显示检索对象

本节中用到的JSP代码如下,代码都简单地很,就不多做解释了。

2.1.1 index.jsp


>
bind an object
</
a
>

>
lookup the binded object
</
a
>

</
body
>

</
html
>

2.1.5 lookup_result.jsp

<%

@ page language
=
"
java
"
 contentType
=
"
text/html; charset=GB18030
"


    pageEncoding
=
"
GB18030
"

%>

<!
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=GB18030"
>

<
title
>
JNDI Test - Lookup result
</
title
>

</
head
>

<
body
>

<%


    
Object
 o 
=
 request.getAttribute(
"
found_jndi_obj
"
);

    out.println(o);

%>

</
body
>

</
html
>

2.2 Servlet

本例包括两个Servlet,功能说明如下:

  • BindServlet:用于在JNDI服务中绑定一个对象
  • LookupServlet:用于在JNDI服务中取出一个对象

2.2.1 BindServlet.java


package
 lld.test.jndi;

import
 java.io.IOException;

import
 java.util.Date;

import
 javax.naming.Context;

import
 javax.naming.InitialContext;

import
 javax.servlet.RequestDispatcher;

import
 javax.servlet.ServletContext;

import
 javax.servlet.ServletException;

import
 javax.servlet.http.
*
;

public
 
class
 BindServlet 
extends
 HttpServlet

{


    
private
 
static
 
final
 
long
 serialVersionUID 
=
 
5219969790998794367L
;


    @Override

    
protected
 
void
 doGet(HttpServletRequest req, HttpServletResponse resp)

            
throws
 ServletException, IOException

{

        
this
.doPost(req, resp);

    }


    @Override

    
protected
 
void
 doPost(HttpServletRequest req, HttpServletResponse resp)

            
throws
 ServletException, IOException

{

        
try

{

            Context jndi_ctx 
=
 
new
 InitialContext();

            String key 
=
 
"
jndi_object
"
;

            jndi_ctx.rebind(key, 
new
 Date());

        }

catch
(Exception ex)

{

            ex.printStackTrace();

        }


        

        ServletContext context 
=
 
this
.getServletContext();

        RequestDispatcher dispatcher 
=
 context.getRequestDispatcher(
"
/bind_result.jsp
"
);

        dispatcher.forward(req, resp);

    }


    

}

使用rebind而不是bind绑定对象是因为,使用bind时,如果已经有对象绑定到该键值上,则会抛出异常。

因为只是示例代码,所以我只是绑定了一个最简单的日期对象。

2.2.2 LookupServlet.java


package
 lld.test.jndi;

import
 java.io.IOException;

import
 javax.naming.Context;

import
 javax.naming.InitialContext;

import
 javax.servlet.RequestDispatcher;

import
 javax.servlet.ServletContext;

import
 javax.servlet.ServletException;

import
 javax.servlet.http.HttpServlet;

import
 javax.servlet.http.HttpServletRequest;

import
 javax.servlet.http.HttpServletResponse;

public
 
class
 LookupServlet 
extends
 HttpServlet

{

    
private
 
static
 
final
 
long
 serialVersionUID 
=
 
6677219828267184673L
;


    @Override

    
protected
 
void
 doGet(HttpServletRequest req, HttpServletResponse resp)

            
throws
 ServletException, IOException

{

        
this
.doPost(req, resp);

    }


    @Override

    
protected
 
void
 doPost(HttpServletRequest req, HttpServletResponse resp)

            
throws
 ServletException, IOException

{

        
try

{

            Context jndi_ctx 
=
 
new
 InitialContext();

            String key 
=
 
"
jndi_object
"
;

            Object o 
=
 jndi_ctx.lookup(key);

            req.setAttribute(
"
found_jndi_obj
"
, o);

        }

catch
(Exception ex)

{

            ex.printStackTrace();

        }


        

        ServletContext context 
=
 
this
.getServletContext();

        RequestDispatcher dispatcher 
=
 context.getRequestDispatcher(
"
/lookup_result.jsp
"
);

        dispatcher.forward(req, resp);

    }


    

}

2.3 web.xml

在web.xml中,加入了servlet映射


<?
xml version="1.0" encoding="UTF-8"
?>

<
web-app 
id
="WebApp_ID"
 version
="2.4"
 xmlns
="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>


    
<
display-name
>
jndi_test
</
display-name
>


    

    
<
servlet
>


        
<
servlet-name
>
BindServlet
</
servlet-name
>


        
<
servlet-class
>
lld.test.jndi.BindServlet
</
servlet-class
>


    
</
servlet
>


    
<
servlet-mapping
>


        
<
servlet-name
>
BindServlet
</
servlet-name
>


        
<
url-pattern
>
/bind.do
</
url-pattern
>


    
</
servlet-mapping
>


    

    
<
servlet
>


        
<
servlet-name
>
LookupServlet
</
servlet-name
>


        
<
servlet-class
>
lld.test.jndi.LookupServlet
</
servlet-class
>


    
</
servlet
>


    

    
<
servlet-mapping
>


        
<
servlet-name
>
LookupServlet
</
servlet-name
>


        
<
url-pattern
>
/lookup.do
</
url-pattern
>


    
</
servlet-mapping
>


    

    
<
welcome-file-list
>


        
<
welcome-file
>
index.jsp
</
welcome-file
>


    
</
welcome-file-list
>

</
web-app
>


OK,所有的代码都在这里了,部署到Tomcat下运行即可。

JNDI 笔记(三) J2SE下使用JNDI

在J2SE下使用JNDI下就显得困难一些,首先,我们没有单独的JNDI服务器可以用,JBoss提供了一个免费的JNP服务,通过配置可以作为
单独的JNDI服务器启用。不过这里就不这么麻烦了,如何使用JBOSS作为JNDI服务器,以后将单独撰文讲述,这里我使用sun提供的
com.sun.jndi.fscontext.RefFSContextFactory作为JNDI服务器,其实这是使用文件系统来存储JNDI对象。
至于如何存储后文还将专门描述。

为了在J2SE下使用JNDI,我们首先得到sun的网站上下载3个包,jndi.jar、fscontext.jar和providerutil.jar,前者提供了JNDI服务的接口,后两者是我们要使用的文件系统作为JNDI服务器的支持包。

使用RefFSContextFactory,要求绑定的对象必须实现javax.naming.Referencable接口,否则在绑定时将报如下错误:

Can only bind References or Referenceable objects

各个JDBC驱动提供商提供的DataSource类都实现了Referencable接口,可以直接使用。不过本着学习的态度,我还是在这里演示一下如何实现Referencable接口。

这个如何实现将在后文结合代码详细介绍。本例包括4个类,说明如下:

  • BindedClass:自定义的实现Referenceable接口的类
  • BindedClassFactory:工厂类,能够把一个Reference对象转换为BindedClass对象
  • Bind:测试类,用于在JNDI中绑定对象
  • Loopup:测试类,用于从JNDI中获取对象

3.1 BindedClass和BindedClassFactory

3.1.1 BindedClass


package
 lld.test.jndi;

import
 javax.naming.NamingException;

import
 javax.naming.Reference;

import
 javax.naming.Referenceable;

import
 javax.naming.StringRefAddr;

public
 
class
 BindedClass 
implements
 Referenceable 

{

    
public
 String value; 

    

    
public
 BindedClass()

{

    }


    

    @Override

    
public
 Reference getReference() 
throws
 NamingException

{

        Reference r 
=
 
new
 Reference(
this
.getClass().getName(), BindedClassFactory.
class
.getName(), 
null
);

        r.add(
new
 StringRefAddr(
"
value
"

this
.getValue()));

        
return
 r;

    }


    
public
 String getValue()

{

        
return
 value;

    }


    
public
 
void
 setValue(String value)

{

        
this
.value 
=
 value;

    }


}

3.1.2 BindedClassFactory


package
 lld.test.jndi;

import
 java.util.Hashtable;

import
 javax.naming.
*
;

import
 javax.naming.spi.
*
;

public
 
class
 BindedClassFactory 
implements
 ObjectFactory

{

    @Override

    
public
 Object getObjectInstance(Object obj, Name name, Context nameCtx,

时间: 2024-08-13 05:10:03

JNDI 笔记(一) 概述的相关文章

学习笔记-性能测试-概述

性能测试的目的,什么是性能测试? 目的主要有四点:1评估系统能力,2寻找系统弱点(瓶颈),3系统调优,4验证系统可靠性,稳定性. 通俗的来说,性能测试的目的就是验证系统好不好用,就像功能测试验证系统是否可以用. 比较官方点的定义是: 是指在某个特定的硬件.软件.网络环境下通过自动化的测试工具模拟多种正常.峰值以及异常负载条件来对系统的各项性能指标进行测试. 性能测试的步骤? 设计测试方案 选择测试工具 搭建测试环境 设计测试场景 执行测试 分析测试结果 性能选择的标准? 达到客户的需求 新系统至

转载 TCPIP学习笔记之概述

1.分层 网络协议通常分不同层次进行开发,每一层分别负责不同的通信功能.一个协议族,比如 T C P / I P,是一组不同层次上的多个协议的组合. T C P / I P通常被认为是一个四层协议系统,其示意图如下: (图1)TCP/IP协议族的四个层次 每一层负责不同的功能: 1) 链路层: 有时也称作数据链路层或网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡.它们一起处理与电缆(或其他任何传输媒介)的物理接口细节. 2)网络层: 有时也称作互联网层,处理分组在网络中的

JNDI 笔记

原理:         在DataSource中事先建立多个数据库连接,保存在数据库连接池中.当程序访问数据库时,只用从连接池中取空闲状态的数据库连接即可,访问结束,销毁资源,数据库连接重新回到连接池,这与每次去直接访问数据库相比,会节省大量时间和资源.         JNDI( Java Naming and Directory Interface ),是Java平台的一个标准扩展,提供了一组接口.类和关于命名空间的概念.如同其它很多Java技术一样,JDNI是provider-based的

Java基础学习笔记-Java概述与环境配置

第一篇 Java 概述与环境配置 一.基础常识:   1.软件开发: <1>什么是软件? 软件:一系列按照特定顺序组织的计算机数据和指令的集合. 常见的软件: 系统软件:如DOS,windows, Linux等. 应用软件:如扫雷,迅雷,QQ等. <2>什么是开发? 制作软件 <3>人机交互 软件的出现实现了人与计算机之间的更好的交互.   交互方式: 图形化界面:这种方式简单直观,使用者易于接受,容易上手操作. 命令行方式:需要有一个控制台,输入特定的指令,让计算机完

Struts2 学习笔记(概述)

Struts2 学习笔记 2015年3月7日11:02:55 MVC思想 Strust2的MVC对应关系如下: 在MVC三个模块当中,struts2对应关系如下: Model: 负责封装应用的状态,并实现应用的功能.通常分为数据模型和业务逻辑模型,数据模型用来存放业务数据,比如订单信息.用户信息等:而业务逻辑模型包含应用的业务操作,比如订单的添加或者修改等. 封装应用状态:某些应用数据封装起来,使得视图只能通过接口获取对应的数据 响应状态查询:对应用的状态改变进行处理 暴露应用功能:暴露接口 通

mongodb 学习笔记 01 -- 概述,安装,运行

mongodb 概述 mongodb 是文档型NoSQL数据库,存储 bson–> json二进制.内部执行引擎为js解释器,把文档存储成bson结构,在查询时,转化为js对象.并可以通过js语法操作. mongodb 与传统数据库比 传统数据库是结构化数据库,列的个数类型都一样 文档数据库 以文档为单位 比如: { id:1, name: "billvsme", age:21, } { id:2, name: "zhangshan", phone:12313

JSP笔记02——概述(译)

不完全翻译,结合谷歌,一定主观性,还可能有误,原始内容地址:https://www.tutorialspoint.com/jsp/jsp_overview.htm 主要内容如下: 什么是JSP? 为什么使用JSP? 什么是JSP? JavaServer Pages (JSP)是一种用于开发支持动态内容的Web页面的技术.开发人员可以通过使用特殊的JSP标签在HTML页面中插入Java代码,这些标签大部分以<%开头,以%>结尾. [注释]感觉直接用英文全名称呼好一点.. JSP事实上是一种Jav

提升强大工作能力的“三种未来笔记”的概述

未来笔记的分类: 整合笔记:头脑清晰,思路有序. 创意笔记:灵感不断涌现. 传达笔记:瞬间就能传达要点. 未来笔记 1 "整合笔记":简单整合信息,让工作有序化的方法. 整合笔记强调的是资料收集和资料整理的重要性,给笔记加上记号的标题,从信息中提炼出"有价值的信息",工作效率立马得到大幅度提升,为创意的产生创造空间. 未来笔记 2 "创意笔记":用笔记的力量,催生大量灵感的方法. 创意就是即存要素(大量使用图纸和绘画)的重新组合罢了. 未来笔记

RMAN_学习笔记1_RMAN概述和体系结构

2014-12-23 Created By BaoXinjian 本文转载乐沙弥大神 一.摘要 是一种用于集备份(backup).还原(restore)和恢复(recover)数据库于一体的Oracle 工具,支持命令行及图形界面操作 能够备份整个数据库.表空间.数据文件.控制文件.归档文件以及Spfile参数文件. 支持增量数据块级别的备份和块级别的介质恢复 可以保存频繁执行的备份恢复脚本 可以实现数据库的克隆.使用RMAN建立备用数据库 支持镜像备份与备份集,可以备份到磁盘与磁带 管理备份与