利用JBOSS+MyEclipse完成一個(gè)簡(jiǎn)單的EJB示例
目標(biāo):
1、編寫一個(gè)簡(jiǎn)單的無狀態(tài)會(huì)話Bean,傳入一個(gè)字符串參數(shù),返回字符串Hello +
字符串參數(shù)。
2、通過JSP頁(yè)面上輸入一個(gè)字符串,提交到Servlet,并調(diào)用EJB,最后在一個(gè)頁(yè)面上輸出處
理后的字符串。
工具:
JBOSS 4.2GA + Eclipse 3.2.2 +MyEclipse 5.5GA + JDK 1.6
首先需要搭建好各種環(huán)境,這一步比較簡(jiǎn)單,就不再贅述。唯一需要注意的是在啟動(dòng)JBOSS
服務(wù)器時(shí)可能會(huì)出現(xiàn)一些問題。如端口號(hào)被占用而導(dǎo)致服務(wù)器無法啟動(dòng)。如果出現(xiàn)這個(gè)問題
可以在%JBOSS%/server/default/deploy/jboss-web.deployer/目錄下找到server.xml文件
,修改<Connector port="8080" address="${jboss.bind.address}"
maxThreads="250" maxHttpHeaderSize="8192"
emptySessionPath="true" protocol="HTTP/1.1"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
中的port屬性,然后再重新啟動(dòng)服務(wù)器。默認(rèn)端口是8080。
JBOSS自帶了TOMCAT
5.X,當(dāng)然也可以使用另外的Web服務(wù)器,不過后面的程序會(huì)稍微有些改動(dòng)。
環(huán)境搭建完成后就需要編寫EJB代碼。一個(gè)EJB至少需要3個(gè)類,即Home接口、遠(yuǎn)程接口、實(shí)
現(xiàn)類。新建一個(gè)EJB Project,項(xiàng)目名為:MyFirstEJB.
-----------------------------------------------------------------------------------------
1、創(chuàng)建Home接口---HelloHome.java
package com;
public interface HelloHome extends javax.ejb.EJBHome {
public Hello create() throws javax.ejb.CreateException,
java.rmi.RemoteException;
}
-----------------------------------------------------------------------------------------
2、創(chuàng)建遠(yuǎn)程接口---Hello.java
package com;
public interface Hello extends javax.ejb.EJBObject {
public String sayHello(String message) throws java.rmi.RemoteException;
}
-----------------------------------------------------------------------------------------
3、創(chuàng)建實(shí)現(xiàn)類---HelloBean.java
package com;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class HelloBean implements SessionBean {
private SessionContext context;
public HelloBean() {
}
public String sayHello(String message) {
if (message == null)
message = "";
message = "i am xiongxiong.Hello " + message + "!";
return message;
}
public void ejbActivate() throws EJBException, RemoteException {
}
public void ejbPassivate() throws EJBException, RemoteException {
}
public void ejbRemove() throws EJBException, RemoteException {
}
public void setSessionContext(SessionContext newContext)
throws EJBException {
context = newContext;
}
public void ejbCreate() throws CreateException {
}
public void replaceWithRealBusinessMethod() throws EJBException {
}
}
-----------------------------------------------------------------------------------------
其中方法sayHello就是我們需要實(shí)現(xiàn)的業(yè)務(wù)。
類建好之后,接下來就需要配置相關(guān)的xml文件。在該項(xiàng)目下的META-INF里新建兩個(gè)xml文件
ejb-jar.xml和jboss.xml。具體配置如下:
-----------------------------------------------------------------------------------------
ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<description>
<![CDATA[No Description.]]>
</description>
<display-name>Generated by XDoclet</display-name>
<enterprise-beans>
<session>
<description>
<![CDATA[Description for Hello]]>
</description>
<display-name>Name for Hello</display-name>
<ejb-name>Hello</ejb-name>
<home>com.HelloHome</home>
<remote>com.Hello</remote>
<ejb-class>com.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
</assembly-descriptor>
</ejb-jar>
-----------------------------------------------------------------------------------------
jboss.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 2.4//EN" "http://www.jboss.org/j2ee/dtd/jboss_2_4.dtd">
<jboss>
<enterprise-beans>
<session>
<ejb-name>Hello</ejb-name>
<jndi-name>ejb/Hello</jndi-name>
</session>
</enterprise-beans>
<resource-managers>
</resource-managers>
</jboss>
-----------------------------------------------------------------------------------------
使用XDoclet來自動(dòng)生成這些文件還是很方便的,只是同時(shí)會(huì)生成一些多余的類和代碼,需
要手動(dòng)去刪除他們。
到這里一個(gè)簡(jiǎn)單的無狀態(tài)會(huì)話Bean就完成了,下面就是將他們部署到Jboss下面??梢詫㈨?xiàng)
目打包成jar文件,然后放在
%JBOSS%/server/default/deploy/目錄下,這樣就算部署完成。還可以使用MyEclipse來幫
你進(jìn)行部署。如果控制臺(tái)上出現(xiàn):
01:59:48,640 INFO [EjbModule] Deploying Hello
01:59:48,703 INFO [ProxyFactory] Bound EJB Home 'Hello' to jndi 'ejb/Hello'
01:59:48,703 INFO [EJBDeployer] Deployed:
file:/%jboss%/server/default/deploy/MyFirstEJB.jar/
就表示部署成功。下面我們就可以編寫客戶端程序來調(diào)用該EJB。
新建一個(gè)Web項(xiàng)目,項(xiàng)目名為testEJB,里面包含兩個(gè)jsp文件和一個(gè)servlet。
-----------------------------------------------------------------------------------------
EJBServlet.java
package com;
import java.io.IOException;
import javax.ejb.CreateException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class EJBServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("gb2312");
String info = request.getParameter("info");
InitialContext context = null;
Hello hello = null;
try {
context = new InitialContext();
HelloHome home = (HelloHome) context.lookup("ejb/Hello");
hello = home.create();
} catch (NamingException e) {
e.printStackTrace();
} catch (CreateException e) {
e.printStackTrace();
}
info = hello.sayHello(info);
request.setAttribute("info", info);
request.getRequestDispatcher("message.jsp").forward(request, response);
}
}
-----------------------------------------------------------------------------------------
從jsp頁(yè)面上獲得表單中的字符串,然后將這個(gè)字符串傳遞到EJB的會(huì)話Bean中進(jìn)行處理。最
后將返回的字符串顯示在另外一個(gè)JSP頁(yè)面上。
-----------------------------------------------------------------------------------------
index.jsp
<%@ page language="java" isELIgnored="false" pageEncoding="gb2312"%>
<html>
<head>
<title>EJB</title>
</head>
<body>
<form action="servlet" method="post">
<input type="text" name="info" />
<input type="submit" value="提交">
</form>
</body>
</html>
-----------------------------------------------------------------------------------------
message.jsp
<%@ page language="java" isELIgnored="false" pageEncoding="utf-8"%>
<html>
<head>
<title>message</title>
</head>
<body>
<h1>${info }</h1>
</body>
</html>
-----------------------------------------------------------------------------------------
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>EJBServlet</servlet-name>
<servlet-class>com.EJBServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EJBServlet</servlet-name>
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
</web-app>
-----------------------------------------------------------------------------------------
如果Web項(xiàng)目和EJB項(xiàng)目在同一服務(wù)器中,那么象上面的程序運(yùn)行是沒什么問題的。
如果Web項(xiàng)目和EJB項(xiàng)目不在同一臺(tái)服務(wù)器中,或者同一臺(tái)服務(wù)器中使用的不是JBOSS自帶的T
omcat,那么創(chuàng)建
ClientTestEJB.java
-----------------------------------------------------------------------------------------
package com;
import java.rmi.RemoteException;
import java.util.Hashtable;
import javax.ejb.CreateException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServlet;
public class ClientTestEJB extends HttpServlet {
public static void main(String[] args) {
String info = "";
InitialContext context = null;
Hello hello = null;
/** *******************添加的代碼**************************** */
Hashtable environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
environment.put(Context.URL_PKG_PREFIXES,
"org.jboss.naming:org.jnp.interfaces");
environment.put(Context.PROVIDER_URL, "jnp://localhost:1099");
/** ******************************************************** */
try {
context = new InitialContext(environment);
HelloHome home = (HelloHome) context.lookup("ejb/Hello");
hello = home.create();
info = hello.sayHello(info);
} catch (RemoteException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
} catch (CreateException e) {
e.printStackTrace();
}
System.out.println(info);
}
}
-----------------------------------------------------------------------------------------
還需要將%jboss%/client/jbossall-client.jar
和EJB項(xiàng)目的jar包拷貝到web 項(xiàng)目中WEB-INF\lib目錄或者CLASSPATH下。
如果不是jsp或servlet調(diào)用EJB不會(huì)出現(xiàn)下面錯(cuò)誤
補(bǔ)充:在jsp或servlet中調(diào)用EJB時(shí)出現(xiàn)下面錯(cuò)誤時(shí):
04:03:33,714 INFO [STDOUT] java.rmi.ServerException: EJBException:; nested
exception is:
javax.ejb.EJBException: Invalid invocation, check your deployment packaging,
method=public abstract test.ejb.TestEJBInterface test.ejb.TestEJBHome.create()
throws javax.ejb.CreateException,java.rmi.RemoteException
解決辦法有三種:
1、編輯%jboss%/server/default/conf/jboss-service.xml
<mbean code="org.jboss.naming.NamingService"
name="jboss:service=Naming"
xmbean-dd="resource:xmdesc/NamingService-xmbean.xml">
<!-- The call by value mode. true if all lookups are unmarshalled using
the caller's TCL, false if in VM lookups return the value by reference.
-->
<attribute name="CallByValue">false</attribute>
...
</mbean>
將屬性CallByValue的值改為true
2、編輯%jboss%/server/default/deploy/ear-deployer.xml
<mbean code="org.jboss.deployment.EARDeployer"
name="jboss.j2ee:service=EARDeployer">
<attribute name="Isolated">false</attribute>
<attribute name="CallByValue">false</attribute>
<attribute name="EnablelibDirectoryByDefault">true</attribute>
</mbean>
將屬性Isolated和CallByValue的值改為true
3、編輯%jboss%/server/default/deploy/jboss-web.deployer/META-INF/jboss-service.x
ml
<attribute name="Java2ClassLoadingCompliance">false</attribute>
<attribute name="UseJBossWebLoader">false</attribute>
將屬性Java2ClassLoadingCompliance和UseJBossWebLoader的值改為false,這里默認(rèn)值一
般都是false
一般情況下,使用第二種方式就可以解決該問題。
posted on 2009-09-14 19:41
大鳥 閱讀(423)
評(píng)論(0) 編輯 收藏 所屬分類:
WEB