使用JNDI和 企业级JAVABEANS


一.在Tomcat中配置JNDI对象

解决方案:在servlet.xml或表示web应用程序的XML文件中创建Resource和ResourceParam元素。然后向web.xml
中添加一个resource-env-ref元素。
tomcat的jndi对象在conf/server.xml文件,就要在这个xml文件中配置jndi对象。
例:配置jndi对象的server.xml元素
<Resource name="bean/pricebean" type=
"com.jspservletcookbook.StockPriceBean" auth="Container" description=
"A web harvesting bean"/>

<ResourceParams name="bean/pricebean">

<parameter>
<name>factory</name>
<value>org.apache.naming.factory.BeanFactory</value>
</parameter>

</ResourceParams>
该例包括一个Resource元素和一个使用名("bean/pricebean")应用该Resource的ResourceParams元素。这个名是
Java代码用来通过JNDI API访问bean实例的地址。

下面的例子将展示卫使web应用程序代码访问该JNDI对象,必须出现在部署描述文件(web.xml)中的resource-env-ref
元素。将com.jsperveltcookbook.StockPriceBean类存储在WEB-INFO/classes或位于WEB-INF/lib的JAR文件中。
例:将此元素放在部署描述文件web.xml中
<!-- 部署描述文件开始部分r -->

<resource-env-ref>

<description>
A factory for StockPriceBean
</description>

<resource-env-ref-name>
bean/pricebean
</resource-env-ref-name>

<resource-env-ref-type>
com.jspservletcookbook.StockPriceBean
</resource-env-ref-type>

</resource-env-ref>

<!-- 部署描述文件的其余部分 -->

下面将展示使用JNDI API 的代码段,只是让你了解该配置如何应用于有关JNDI的代码。
例:访问一个Tomcat JNDI资源的代码片段
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

//此代码可以放在servlet的init()方法,或者doGet()或doPos t()中

Context env = null;

StockPriceBean spbean = null;

try{

env = (Context) new InitialContext( ).lookup("java:comp/env");

spbean = (StockPriceBean) env.lookup("bean/pricebean");

if (spbean == null)
throw new ServletException(
"bean/pricebean is an unknown JNDI object");

//如果不再使用,关闭InitialContext
env.close( );

} catch (NamingException ne) {

//close the Context if you're not using it again
try{ env.close( ); } catch(NamingException nex) {}

throw new ServletException(ne);
}

在servlet中访问Tomcat JNDI资源
进行如下步骤之后,servlet就可以作为JNDI注册资源来访问JavaBean:
1.开发该JavaBean类,并将其存储在WEB-INF/classes或WEB-INF/lib下的JAR中。
2.为将该对象绑定与Tomcat JNDI 树,要如前面所述,修改服务器配置文件和web.xml。
下面将在其init()方法中创建一个javax.naming.InitialContext,然后查找一个JavaBean:com.jspservletcookbook.StockPriceBean.
这个bean用名"bean/pricebean"绑定于JNDI实现。init()方法只是在servlet容器创建servlet实例时才被调用,因此该servlet只访问
一个StockPriceBean的实例。
例:在servlet中使用Tomcat JNDI对象
package com.jspservletcookbook;

import java.io.IOException;
import java.io.PrintWriter;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.servlet.*;
import javax.servlet.http.*;

public class BeanServlet extends HttpServlet {

private StockPriceBean spbean;

public void init( ) throws ServletException {

Context env = null;

try{

env = (Context) new InitialContext( ).lookup("java:comp/env");

spbean = (StockPriceBean) env.lookup("bean/pricebean");

//关闭InitialContext,除非代码将用它来进行另一次查找
env.close( );

if (spbean == null)
throw new ServletException(
"bean/pricebean is an unknown JNDI object");

} catch (NamingException ne) {

try{ env.close( );} catch (NamingException nex) { }

throw new ServletException(ne);

}//try

}//init

public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {

//设置响应的MIME类型:"text/html"
response.setContentType("text/html");

//使用PringWriter向客户端发送文本数据
java.io.PrintWriter out = response.getWriter( );

//开始组装HTML内容
out.println("<html><head>");

out.println("<title>Stock Price Fetcher</title></head><body>");
out.println("<h2>Please submit a valid stock symbol</h2>");

//确保method="POST",这样servlet服务方法在响应此表单提交时会调用doPost
//calls doPost in the response to this form submit
out.println(
"<form method=/"POST/" action =/"" + request.getContextPath( ) +
"/namingbean/" >");

out.println("<table border=/"0/"><tr><td valign=/"top/">");
out.println("Stock symbol: </td> <td valign=/"top/">");
out.println("<input type=/"text/" name=/"symbol/" size=/"10/">");
out.println("</td></tr><tr><td valign=/"top/">");

out.println(
"<input type=/"submit/" value=/"Submit Info/"></td></tr>");

out.println("</table></form>");
out.println("</body></html>");

} //doGet

public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws java.io.IOException{

String symbol;//这将保存股票代号

float price = 0f;

symbol = request.getParameter("symbol");

boolean isValid = (symbol == null || symbol.length( ) < 1) ?
false : true;

//set the MIME type of the response, "text/html"
response.setContentType("text/html");

//use a PrintWriter send text data to the client
java.io.PrintWriter out = response.getWriter( );

//Begin assembling the HTML content
out.println("<html><head>");
out.println("<title>Latest stock value</title></head><body>");

if ((! isValid) || spbean == null){
out.println(
"<h2>Sorry, the stock symbol parameter was either "+
"empty or null</h2>");

} else {

out.println("<h2>Here is the latest value of "+ symbol +"</h2>");
spbean.setSymbol(symbol);
price = spbean.getLatestPrice( );
out.println( (price==0?
"The symbol is probably invalid." : ""+price) );
}
out.println("</body></html>");
}//doPost
}//BeanServlet

下面的例子将展示Tomcat在存储为JNDI对象的bean(即上面使用的bean).

例:存储为JNDI对象的bean

package com.jspservletcookbook;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.MalformedURLException;

import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.parser.ParserDelegator;

public class StockPriceBean {

private static final String urlBase =
"http://finance.yahoo.com/q?d=t&s=";
private BufferedReader webPageStream = null;
private URL stockSite = null;
private ParserDelegator htmlParser = null;
private MyParserCallback callback = null;
private String htmlText = "";
private String symbol = "";
private float stockVal = 0f;

public StockPriceBean( ) {}//该bean的不带参数的构造函数

public void setSymbol(String symbol){
this.symbol = symbol;
}

public String getSymbol( ){
return symbol;
}

//提供回掉的内部类
class MyParserCallback extends ParserCallback {

private boolean lastTradeFlag = false;
private boolean boldFlag = false;
public MyParserCallback( ){
if (stockVal != 0)
stockVal = 0f;
}

public void handleStartTag(javax.swing.text.html.HTML.Tag t,
MutableAttributeSet a,int pos) {
if (lastTradeFlag && (t == javax.swing.text.html.HTML.Tag.B )){
boldFlag = true;
}
}//handleStartTag

public void handleText(char[] data,int pos){
htmlText = new String(data);
if (htmlText.indexOf("No such ticker symbol.") != -1){
throw new IllegalStateException(
"Invalid ticker symbol in handleText( ) method.");
} else if (htmlText.equals("Last Trade:")){
lastTradeFlag = true;
} else if (boldFlag){

try{
stockVal = new Float(htmlText).floatValue( );
} catch (NumberFormatException ne) {

try{
//使用NumberFormat去掉数字中的所有逗号
java.text.NumberFormat nf = java.text.NumberFormat.
getInstance( );
Double f = (Double) nf.parse(htmlText);
stockVal = (float) f.doubleValue( );
} catch (java.text.ParseException pe){
throw new IllegalStateException(
"The extracted text " + htmlText +
" cannot be parsed as a number!");
}//inner try

}//outer try
lastTradeFlag = false;
boldFlag = false;

}//if
} //handleText
}//MyParserCallback

public float getLatestPrice( ) throws IOException,MalformedURLException {

stockSite = new URL(urlBase + symbol);
webPageStream = new BufferedReader(new InputStreamReader(stockSite.
openStream( )));
htmlParser = new ParserDelegator( );
callback = new MyParserCallback( );//ParserCallback

synchronized(htmlParser){
htmlParser.parse(webPageStream,callback,true);
}//sychronized

//reset symbol
setSymbol("");
return stockVal;

}//getLatestPrice
}//StockPriceBean

注意:ParserDelegator.parse()方法是同步的,因此在用以时间只允许一个线程解析该Web叶面并提供股票价格
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
在JSP中访问Tomcat JNDI资源
解决方案:使用过滤器将对象放置在请求或会话范围中。在JSP中使用c:set和c:out JSTL标记访问该对象
过滤器的一个好的任务是访问JNDI对象,然后将对象的引用放置在会话中,交给JSP使用。
下面是通过JNDI和JSP使用过滤器所需的步骤:
1.开发并编辑过滤器,包括一个不带参数的构造函数。
2.在过滤其中使用JNDI API和javax.naming包来设置一个使用JNDI对象的会话属性。
3.将过滤器放置在WEB-INF/classes或WEB-INF/lib的jar中。
4.向web.xml中添加filter和filter-mapping元素,将过滤器映射到使用JNDI对象的JSP。
5.创建使用该会话属性的JSP。

例:过滤器访问JNDI对象并将此对象设置为会话属性
package com.jspservletcookbook;

import java.io.IOException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.servlet.*;
import javax.servlet.http.*;

public class JndiTFilter implements Filter {

private FilterConfig config;
private Context env;

//不带参数的构造函数对于过滤器是必需的
//虽然在缺少这样或其他的构造函数时,编译器回创建一个,但这里仍然显式地生成这个构造函数
public JndiTFilter( ) {}

public void init(FilterConfig filterConfig) throws ServletException {

this.config = filterConfig;
try {
env = (Context) new InitialContext( ).lookup("java:comp/env");
env.close( );
} catch (NamingException ne) {
try{ env.close( ); } catch (NamingException nex) {}
throw new ServletException(ne);
}
}

public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException,
ServletException {

StockPriceBean spbean = null;

try {
spbean = (StockPriceBean) env.lookup("bean/pricebean");
} catch (NamingException ne) { }

HttpServletRequest hRequest = null;
if (request instanceof HttpServletRequest)
hRequest = (HttpServletRequest) request;

HttpSession hSession = hRequest.getSession( );
if (hSession != null)
hSession.setAttribute("MyBean",spbean);


chain.doFilter(request,response);
}// doFilter

public void destroy( ){
/*在web窗口将该过滤器实例从服务器中移除前调用*/
}
}//Filter
过滤器的doFilter()方法将在每次客户端请求JSP时调用,所以每个客户端都与不同 的bean实例关联。也就是说,
每个会话都存储其自己的bean实例 。

下面将展示添加到部署描述文件中的filter和filter-mapping元素。这将使得servlet容器创建该过滤器的一个实例(调用
过滤器的init()方法)。这样,在每次接收到与filter-mapping元素中所关联的URL相同的请求时,容器将调用过滤器的
doFilter()方法。
例:用于与JNDI相关过滤器的filter和filter-mapping元素
<!-- start of web.xml -->

<filter>

<filter-name>JndiTFilter</filter-name>
<filter-class>com.jspservletcookbook.JndiTFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>JndiTFilter</filter-name>
<url-pattern>/jndiJsp.jsp</url-pattern>

</filter-mapping>

<!-- rest of web.xml -->

下面将JndiTFilter映射到URL为/jndiJsp.jsp的Web组件。
例:JSP使用一个作为JNDI对象生成的会话属性
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

<html>
<head><title>Jndi Bean</title></head>
<body>
<h2>Getting a StockPriceBean object via JNDI...</h2>

<c:set var="priceBean" value="${MyBean}"/>

<%-- 设置symbol特性为股票代号 --%>
<c:set target="${priceBean}" property="symbol" value="${param.symbol}"/>

<%-- 通过调用该bean对象的getLatestPrice()或的最新价格 --%>
The latest price: <c:out value="${priceBean.latestPrice}" />

</body>
</html>

二.在Weblogic种配置JNDI资源

下面是将javax.mail.Session对象绑定于Weblogic的JNDI实现所需的步骤。
1.登陆Weblogic管理控制台,包括使用浏览器URL,如http://localhost:7001/console.
2.使用在左侧栏中Your-domain-name Services Mail菜单。
3.单击"Configure a new Mail Session...".
4.在生成的窗口种填写文本域。为Session对象赋予一个JNDI名(在"jndiname"下),这将是代码用来查找该对象的名。
5.输入Session的所有特性:健入特性名,一个等号(=)和特性值。
6.单击Apply按钮,然后选择Targets标签。生成的屏幕允许将JNDI对象与一个或多个服务器相关联。

为本技巧的 Session JNDI对象设置的JavaMail特性

特性名描述示例
mail.host默认的邮件服务器mail.comcastl.net
mail.smtp.host特定协议的邮件主机,默认mail.comcast.net
情况为mail.host的值
mail.user连接邮件服务器的用户名bruceperry
mail.from发送邮件时使用的返回地址[email protected]

在servlet种访问Weblogic JNDI资源

下面是一个包含Weblogic的JNDI实现中javax.mail.Session对象的HttpServlet.
该servlet使用此对象构建一个电子邮件消息。该servlet在其init()方法中查找以名"MyEmail"绑定的对象。servlet
容器在创建该servlet实例时调用init()一次

例:从Weblogic的JNDI实现中获取一个javax.mail.Session 对象并构建电子邮件消息的servlet
package com.jspservletcookbook;

import java.io.IOException;
import java.io.PrintWriter;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.mail.*;
import javax.mail.internet.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class EmailJndiServlet extends HttpServlet {

private Session mailSession;

public void init( ) throws ServletException {

Context env = null;

try{

env = (Context) new InitialContext( );
mailSession = (Session) env.lookup("MyEmail");
if (mailSession == null)
throw new ServletException(
"MyEmail is an unknown JNDI object");

//close the InitialContext
env.close( );

} catch (NamingException ne) {
try{ env.close( );} catch (NamingException nex) { }
throw new ServletException(ne);
}
}//init

public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
java.io.IOException {

response.setContentType("text/html");
java.io.PrintWriter out = response.getWriter( );

out.println(
"<html><head><title>Email message sender</title></head><body>");

String to = request.getParameter("to");
String from = request.getParameter("from");
String subject = request.getParameter("subject");
String emailContent = request.getParameter("emailContent");
try{
sendMessage(to,from,subject,emailContent);
} catch(Exception exc){
throw new ServletException(exc.getMessage( ));
}


out.println(
"<h2>The message was sent successfully</h2></body></html>");

out.println("</body></html>");

} //doPost

public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
java.io.IOException {

//doGet( ) calls doPost( )
doPost(request,response);

}

private void sendMessage(String to, String from, String subject,
String bodyContent) throws Exception {

Message mailMsg = null;

mailMsg = new MimeMessage(mailSession);//a new email message
InternetAddress[] addresses = null;

try {
if (to != null) {

//如果to电子邮件地址违反RFC822语法,则抛出AddressException
addresses = InternetAddress.parse(to, false);
mailMsg.setRecipients(Message.RecipientType.TO, addresses);

} else {
throw new MessagingException(
"The mail message requires a 'To' address.");
}

if (from != null)
mailMsg.setFrom(from);

if (subject != null)
mailMsg.setSubject(subject);

if (bodyContent != null)
mailMsg.setText(bodyContent);

//最后,发送该邮件消息,如果消息的任何一个接收地址无效,则抛出一个"SendFailException
Transport.send(mailMsg);

} catch (Exception exc) {
throw exc;
}//sendMessage
}//EmailJndiServlet
对该servlet的典型请求如下:
http://localhost:7001/[email protected]&
[email protected]&subject=hello&
emailContent=A web message


在JSP中访问Weblogic JNDI 资源

例:过滤器将Weblogic JNDI对象存储于会话属性
package com.jspservletcookbook;

import java.io.IOException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.servlet.*;
import javax.servlet.http.*;

public class JndiFilter implements Filter {

private FilterConfig config;
private Context env;

public JndiFilter( ) {}

public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
try {
env = (Context) new InitialContext( );
} catch (NamingException ne) {
throw new ServletException(ne);
}
}//init

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {

javax.mail.Session mailSession = null;
try {
mailSession = (javax.mail.Session) env.lookup("MyEmail");
} catch (NamingException ne) { }

HttpServletRequest hRequest = null;
if (request instanceof HttpServletRequest){
hRequest = (HttpServletRequest) request;
HttpSession hSession = hRequest.getSession( );
if (hSession != null)
hSession.setAttribute("MyEmail",mailSession);

}//if
chain.doFilter(request,response);

}// doFilter

public void destroy( ){
/*在web窗口将该过滤器实例从服务器中移除前调用*/
}
}

下面展示了该过滤器在部署描述文件中的配置,此部署描述文件必须伴随一个已被你或另外的部署人员安装于
Weblogic服务器的web应用程序。
例:过滤器在Weblogic 中访问JNDI对象
<!-- start of web.xml -->

<filter>

<filter-name>JndiFilter</filter-name>
<filter-class>com.jspservletcookbook.JndiFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>JndiFilter</filter-name>
<url-pattern>/jndiJsp.jsp</url-pattern>

</filter-mapping>

<!-- rest of web.xml -->

下面将展示一个访问该JNDI对象的JSP.
例:JSP作为会话属性访问JavaMail对象
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

<html>
<head><title>Jndi Email</title></head>
<body>
<h2>Getting a javax.mail.Session object via JNDI...</h2>

<c:set var="mSession" value="${MyEmail}" />

<c:out value="${mSession.class.name}" />

</body>
</html>
________________________________________________________________________________________________

使用Weblogic JNDI树访问EJB

解决方案:找到该EJB的JNDI名,使用javax.naming包获得对该EJBObject或远程接口的引用,这样可以调用该EJB的方法
例:无状态会话EJB

package com.jspservletcookbook;

import javax.ejb.*;

import java.util.Map;
import java.util.HashMap;

public class AbbrevBean implements SessionBean{

private SessionContext context;
private Map abbrevMap;


public AbbrevBean( ){ //the bean's no-arguments constructor

//包含各州名和所写的Map
abbrevMap = new HashMap( );

abbrevMap.put("ALABAMA","AL");
abbrevMap.put("ALASKA","AK");
abbrevMap.put("AMERICAN SAMOA","AS");
abbrevMap.put("ARIZONA","AZ");
abbrevMap.put("ARKANSAS","AR");
abbrevMap.put("CALIFORNIA","CA");
abbrevMap.put("COLORADO","CO");
abbrevMap.put("CONNECTICUTT","CT");

abbrevMap.put("DELAWARE","DE");
abbrevMap.put("DISTRICT OF COLUMBIA","DC");
abbrevMap.put("FEDERATED STATES OF MICRONESIA","FM");
abbrevMap.put("FLORIDA","FL");
abbrevMap.put("GEORGIA","GA");
abbrevMap.put("GUAM","GU");
abbrevMap.put("HAWAII","HI");
abbrevMap.put("IDAHO","ID");

abbrevMap.put("ILLINOIS","IL");
abbrevMap.put("INDIANA","IN");
abbrevMap.put("IOWA","IA");
abbrevMap.put("KANSAS","KS");
abbrevMap.put("KENTUCKY","KY");
abbrevMap.put("LOUISIANA","LA");

abbrevMap.put("MAINE","ME");
abbrevMap.put("MARSHALL ISLANDS","MH");
abbrevMap.put("MARYLAND","MD");
abbrevMap.put("MASSACHUSETTS","MA");
abbrevMap.put("MICHIGAN","MI");
abbrevMap.put("MINNESOTA","MN");

abbrevMap.put("MISSISSIPPI","MS");
abbrevMap.put("MISSOURI","MO");
abbrevMap.put("MONTANA","MT");
abbrevMap.put("NEBRASKA","NE");
abbrevMap.put("NEVADA","NV");
abbrevMap.put("NEW HAMPSHIRE","NH");

abbrevMap.put("NEW JERSEY","NJ");
abbrevMap.put("NEW MEXICO","NM");
abbrevMap.put("NEW YORK","NY");
abbrevMap.put("NORTH CAROLINA","NC");
abbrevMap.put("NORTH DAKOTA","ND");
abbrevMap.put("NORTHERN MARIANA ISLANDS","MP");

abbrevMap.put("OKLAHOMA","OK");
abbrevMap.put("OREGON","OR");
abbrevMap.put("PALAU","PW");
abbrevMap.put("PENNSYLVANIA","PA");
abbrevMap.put("PUERTO RICO","PR");
abbrevMap.put("RHODE ISLAND","RI");
abbrevMap.put("SOUTH CAROLINA","SC");
abbrevMap.put("SOUTH DAKOTA","SD");

abbrevMap.put("TENNESSEE","TN");
abbrevMap.put("TEXAS","TX");
abbrevMap.put("UTAH","UT");
abbrevMap.put("VERMONT","VT");
abbrevMap.put("VIRGIN ISLANDS","VI");
abbrevMap.put("VIRGINIA","VA");
abbrevMap.put("WASHINGTON","WA");
abbrevMap.put("WEST VIRGINIA","WV");
abbrevMap.put("WISCONSIN","WI");
abbrevMap.put("WYOMING","WY");

}//constructor

public void setSessionContext(SessionContext ctx) throws
EJBException {
context = ctx;
}//setSessionContext

public Map getAbbrevMap( ){
return abbrevMap;
}

//这个bean的业务方法
public String getAbbreviation(String state){
return (String) abbrevMap.get(state);
}

//javax.ejb.SessionBean方法,必须在会话bean中实现,但与无状态会话bean无关
//bean, but is not relevant to Stateless session beans.
public void ejbActivate( ){}

//javax.ejb.SessionBean方法,必须在会话bean中实现,但与无状态会话bean无关
//bean, but is not relevant to stateless session beans.
public void ejbPassivate( ){}

//javax.ejb.SessionBean方法;
public void ejbRemove( ) {}
}

下面的ejb-jar.xml文件指定EJB类型和与其相关的java类的完全限定名。
例:ejb-jar.xml文件
<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.
//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd"
>

<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>AbbreviationEjb</ejb-name>
<home>com.jspservletcookbook.AbbrevHome</home>
<remote>com.jspservletcookbook.Abbrev</remote>
<local-home>com.jspservletcookbook.AbbrevLocalHome</local-home>
<local>com.jspservletcookbook.AbbrevLocal</local>
<ejb-class>com.jspservletcookbook.AbbrevBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>

包括此EJB并不属于应用程序服务器的包,是一个名为myejb.jar的jar文件

注意:"主"对象(home object)是"主"接口的实现,"本地主"对象(local home object)是本地主接口的实现。这些
对象是EJB对象的"工厂",这回将业务方法调用委托给部署于服务器的EJB.工厂是生成各种Java类对象的Java类。在
本技巧中,客户端使用JNDI获得对主对象的引用,这将创建一个EJB对象。然后servlet(客户端)调用EJB对象的
getAbbreviation()方法;该EJB对象是一个将此方法调用委托给存储在服务其中的最初的EJB的远程对象或"跟"(stub)

注意:当使用管理控制台在Weblogic中部署EJB时,Weblogic自动使用weblogic-ejb-jar.xml部署描述文件指定的名
将主对象和本地主对象绑定于Weblogic JNDI 树。

下面将展示用于这里无状态会话bean的weblogic-ejb-jar.xml部署描述文件。
例:weblogic-ejb-jar.xml文件
<!DOCTYPE weblogic-ejb-jar PUBLIC
'-//BEA Systems, Inc.//DTD WebLogic 7.0.0 EJB//EN'
'http://www.bea.com/servers/wls700/dtd/weblogic-ejb-jar.dtd'>

<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>AbbreviationEjb</ejb-name>
<stateless-session-descriptor>
<pool>
<initial-beans-in-free-pool>1</initial-beans-in-free-pool>
</pool>
</stateless-session-descriptor>
<jndi-name>AbbrevHome</jndi-name>
<local-jndi-name>AbbrevLocalHome</local-jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>

例:ejb-jar.xml文件的内容
H:/book/cookbook/code/chap27/src/ejbs/ejbjar>jar tvf myejb.jar

META-INF/
META-INF/MANIFEST.MF
com/
com/jspservletcookbook/
com/jspservletcookbook/Abbrev.class
com/jspservletcookbook/AbbrevBean.class
com/jspservletcookbook/AbbrevHome.class
com/jspservletcookbook/AbbrevLocal.class
com/jspservletcookbook/AbbrevLocalHome.class

META-INF/ejb-jar.xml
META-INF/weblogic-ejb-jar.xml

例:在weblogic中使用JNDI访问EJB的sevelt
package com.jspservletcookbook;

import java.io.IOException;
import java.io.PrintWriter;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.rmi.PortableRemoteObject;

import javax.servlet.*;
import javax.servlet.http.*;

public class WebJndiServlet extends HttpServlet {

public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {

//请求参数如state=Messachusetts
String state = request.getParameter("state");
Context env = null;
Abbrev abbrev = null;
AbbrevHome home = null;

try{

env = (Context) new InitialContext( );

//在weblogic JNDI树中查找主对象或工厂对象
Object localH = env.lookup("AbbrevHome");

//这个方法调用对于使用RMI-IIOP技术的EJB代码来讲是必需的
home = (AbbrevHome) PortableRemoteObject.narrow(localH,
AbbrevHome.class);

//close the InitialContext
env.close( );

if (home == null)
throw new ServletException(
"AbbrevHome is an unknown JNDI object");

//通过调用主对象的create()方法获得远程接口
abbrev = (Abbrev) PortableRemoteObject.narrow(home.create( ),
Abbrev.class);

} catch (NamingException ne) {
try{ env.close( );} catch (NamingException nex) { }
throw new ServletException(ne);
} catch (javax.ejb.CreateException ce) {
throw new ServletException(ce);
}


//set the MIME type of the response, "text/html"
response.setContentType("text/html");

java.io.PrintWriter out = response.getWriter( );

out.println("<html><head>");

out.println("<title>State abbreviations</title></head><body>");
out.println("<h2>Here is the state's abbreviation</h2>");

//调用EJBObject的getAbbreviation()方法
//该EJBObject将这个方法调用委托给会话bean
//将所有请求参数变为大写,因为这是会话bean的java.util.Map存储Map的键
//即州名的方式

if (state != null)
out.println( abbrev.getAbbreviation(state.toUpperCase( )) );

try{
//该servlet结束使用此EJBObject;调用其remove()方法
abbrev.remove( );
} catch (javax.ejb.RemoveException re){}

out.println("</body></html>");

}//doGet

public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {

doGet(request, response);

}//doPost

}//WebJndiServlet

一个请求该servlet的URL:http://localhost:7001/webjndi?state=Oregon.


你可能感兴趣的:(javabean)