使用JNDI和 企业级JAVABEANS

来源:互联网 发布:mac os x sierraDMG 编辑:程序博客网 时间:2024/06/05 11:54


一.在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.