`

使用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发送邮件时使用的返回地址author@jspservletcookbook.com

在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?to=author@jspservletcookbook.com&
from=bwperry@parkerriver.com&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.


分享到:
评论

相关推荐

    Java数据编程指南

    本书将向读者介绍如何使用Java开发企业级的分布式应用程序,其中涉及生成、处理、存储、 与检索各种类型的数据与不同的数据库。 本书按照一定的逻辑顺序分为六个部分。在相互的基础上,前四部分深入广泛地探讨了...

    JSP高级编程

    本书从最基础的JSP开发开始,循序渐进地介绍了JSP 开发技术,并涵盖了许多高级主题,如需要在企业级Web应用中使用的特性—Enterprise JavaBeans、JDBC 2.0、数据库连接池和自定义标签库。本书既适合初学者阅读,也...

    Java测试新技术TestNG和高级概念.part2

    4.3 Java命名和目录接口(JNDI) 4.4 Java数据库连接(JDBC) 4.5 Java事务API(JTA) 4.6 Java消息服务(JMS) 4.7 Java持久API(JPA) 4.8 Enterprise JavaBeans 3.0(EJB3) 4.9 Java API for XML Web Services...

    Java测试新技术TestNG和高级概念.part1

    4.3 Java命名和目录接口(JNDI) 4.4 Java数据库连接(JDBC) 4.5 Java事务API(JTA) 4.6 Java消息服务(JMS) 4.7 Java持久API(JPA) 4.8 Enterprise JavaBeans 3.0(EJB3) 4.9 Java API for XML Web Services...

    《Java核心技术 卷II:高级特性(原书第8版)》(中文高清PDF) 第三部分(一共三部分)

    本书聚焦于Java语言中更高级的特性,包括下列内容:流与文件、网络、数据库编程、XML、JNDI与LDAP、国际化、高级 GUI组件、Java 2D、JavaBeans、安全、RMI与Web服务、高级AWT、注解、本地方法。

    JAVA核心技术卷II:高级特性

    本书聚焦于Java语言中更高级的特性,包括下列内容:流与文件、网络、数据库编程、XML、JNDI与LDAP、国际化、高级GUI组件、Java 2D、JavaBeans、安全、RMI与Web服务、高级AWT、注解、本地方法。  关于Java基础知识的...

    《Java核心技术 卷II:高级特性(原书第8版)》(中文高清PDF) 第二部分(一共三部分)

    本书聚焦于Java语言中更高级的特性,包括下列内容:流与文件、网络、数据库编程、XML、JNDI与LDAP、国际化、高级 GUI组件、Java 2D、JavaBeans、安全、RMI与Web服务、高级AWT、注解、本地方法。

    JAVA面试题最全集

    介绍在Jsp中如何使用JavaBeans。 8.简单介绍JSP的标记库 9.Jsp和Servlet中的请求转发分别如何实现。 三、J2EE相关知识 1.介绍J2EE、J2SE、J2SE的区别。 2.J2EE是一种技术还是一种平台,他提供了那些技术。 3....

    java 面试题 总结

    ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector...

    超级有影响力霸气的Java面试题大全文档

     ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    它使用服务层框架可以将JavaBeans从Jsp/Servlet中分离出来,而使用表现层框架则可以将Jsp中剩余的JavaBeans完全分离,这部分JavaBeans主要负责显示相关信息,一般是通过标签库(Taglib)实现,不同框架有不同自己的...

Global site tag (gtag.js) - Google Analytics