当前位置: 代码迷 >> 综合 >> 调用本地会话Bean和远程会话BEAN/EJB的简单例子(环境:JBOSS7.1 JDK7)
  详细解决方案

调用本地会话Bean和远程会话BEAN/EJB的简单例子(环境:JBOSS7.1 JDK7)

热度:13   发布时间:2023-12-29 22:49:44.0

一个小的调用本地EJB的作业,不难,接口什么的非常好写,但是由于网上的jndi千奇百怪,而且这个东西太老了,我上课也没听,导致只能搞个远程的,本地的概念什么的都不是很清楚,所以弄了很久。(环境:JDK7+eclipse+JBOSS7.1)

一会有空总结一下,主要参考老师的PPT(慕课网站 http://mooc1.chaoxing.com/course/203574850.html)和这两篇博客。

  1. https://blog.csdn.net/u010924834/article/details/51114428 
  2. https://blog.csdn.net/u010924834/article/details/51123010

非常感谢(之前的文章编辑完不能保存和发布,只好重新发一个)

一、调用远程接口

新建一个EJB 项目,创建无状态会话Bean远程接口及其实现类,然后Run on server(这时可以在控制台上看到JBOSS的信息,最后应该有Deploy "XXX.jar"),这是前提

此处仅仅放一下Reomote接口的代码,示意一下,因为这个包名很长,怕后面大家有点乱

package javaee.ejb.stateless;import javax.ejb.Remote;@Remote
public interface HelloBeanRemote {public String sayHello(String name);
}

注意远程接口的含义是客户端和服务器不在一个JVM上等,反正就是不在一起。所以我们使用一个普通的JavaApplication进行测试。

新建一个Java Project,新建一个带有main函数的public class。

main函数里面调用EJB的过程将使用JNDI和EJB API实现,见下方。

1.使用EJB CLIENT API调用(推荐)

先在此谈一下最重要的配置动作:

(1) 把jboss-client.jar加入到项目(右键工程-Build Path –Configure  Build Path-ADD external JARS ),这个在JBOSS安装目录/bin/client下

(2)把远程接口类的.java文件按照原样拷贝到src中,即直接报EJB项目中remote接口的文件所在的包一起拷贝过来,然后删掉没有用的文件(这步的作用和链接1中的导入jar包是一样的)

(3)在src下新建jndi.properties文件,内容如下:

endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=admin
remote.connection.default.password=123456

注意username和password换成你自己的

(4)main函数所在类的代码(具体含义可以参考注释和链接1,链接1中讲得更好)

?
?
package statelessClient;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException; import javaee.ejb.stateless.HelloBeanRemote;//远程接口public class HelloWorldClient {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubHashtable<String, String> jndiProperties = new Hashtable<String, String>();jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");try {Context context = new InitialContext(jndiProperties);final String appName = "";final String moduleName = "SessionEJB";//EJB项目名字final String distinctName = "";System.out.println("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/HelloBean!javaee.ejb.stateless.HelloBeanRemote");Object obj = context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/HelloBean!javaee.ejb.stateless.HelloBeanRemote");//此处!后是带包名的remote接口,/和!之间的remote会话beanHelloBeanRemote hwr =(HelloBeanRemote)obj;String say = hwr.sayHello("Jilin University");System.out.println(say);} catch (NamingException e) {e.printStackTrace();}}}??

2.使用通用JNDI (配置动作和上面基本一样,需要buildpath、拷贝remote接口类的完整路径、jndi.proporties)

main函数:

package statelessClient;import java.util.Properties;import javaee.ejb.stateless.HelloBeanRemote;import javax.naming.Context;
import javax.naming.InitialContext;public class HelloWorldClient2 {public static void main(String[] args) {// TODO Auto-generated method stubProperties prop = new Properties();//服务器的命名和目录管理地址prop.put(Context.PROVIDER_URL, "remote://localhost:4447");//初始化上下文环境工厂prop.put(Context.INITIAL_CONTEXT_FACTORY, org.jboss.naming.remote.client.InitialContextFactory.class.getName());//用户验证prop.put(Context.SECURITY_PRINCIPAL,System.getProperty("username","test"));prop.put(Context.SECURITY_CREDENTIALS,System.getProperty("password","123456"));try{Context ctx = new InitialContext(prop);Object obj = ctx.lookup("SessionEJB/HelloBean!javaee.ejb.stateless.HelloBeanRemote");/*实际访问的是java:jboss/exported/SessionEJB/HelloBean!javaee.ejb.stateless.HelloBeanRemote*/HelloBeanRemote hwr = (HelloBeanRemote)obj;String say = hwr.sayHello("Jilin University");System.out.println(say);} catch (Exception e) {e.printStackTrace();}}}

远程接口的就到此结束,下面我们说一下怎么调用本地接口,同样是两种方法,一种是JNDI,一种是依赖注入(推荐)

同样首先要创建一个EJB项目,实现local接口,run on server。

此时我们要在WEB项目上测试,保证可以直接调用local接口

1、依赖注入方式(使用servlet作为示例)

相关配置动作:在新建的web project中,将local接口的完整路径拷贝过来,这个动作与上面的远程调用动作相同。注意只需要这个就可以了

然后新建一个Servlet,代码如下:(本地接口里的方法是获取当前时间,所以运行之后可以看到当前时间)

package EJBServletTest;import java.io.IOException;
import java.io.PrintWriter;import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class TestServlet*/
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {private static final long serialVersionUID = 1L;@EJB javaee.ejb.stateless.TimeBeanLocal  tb;   /*** @see HttpServlet#HttpServlet()*/public TestServlet() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubthis.doPost(request, response);}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubPrintWriter out=null;try{response.setContentType("text/html;charset=UTF-8");out = response.getWriter();out.println("<html>");out.println("<head>");out.println("<title>依赖注入无状态会话Bean本地接口</title>");  out.println("</head>");out.println("<body>");           String str=tb.printTime();out.print("<br>通过依赖注入调用本地接口EJB<br>"+str+"<br>");}catch(Exception e){e.printStackTrace();out.print("<br>本地接口调用失败!");}finally{out.println("</body>");  out.println("</HTML>");out.flush();out.close();}}}

这个Servlet的代码完成之后,直接右键该文件-run on server即可

2、通过JNDI方式

我们以一个index.jsp文件为例。

相关配置动作:右键已经创建好的local接口EJB项目-export-EJB JAR FILE,起名字选择一个位置保存,然后将这个JAR包拷贝到当前web项目的WEBCONTENT-WEB INF-lib目录下。

jsp文件的代码:

<%@ page language="java" import="javax.naming.*, javaee.ejb.stateless.*,java.util.*" pageEncoding="gb2312"%>
<!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=gb2312">
<title>JNDI无状态会话Bean本地接口</title>
</head>
<body>
<!-- 通过接口调用类 --><%System.out.println("1111");try{InitialContext ctx = new InitialContext();final String appName = "";final String moduleName = "homework2_client";final String distinctName = "";//实现类名final String beanName = "TimeBean";//out.println(beanName);//接口类名final String viewClassName = TimeBeanLocal.class.getName();//out.println(viewClassName);String jndi = "java:app/"+moduleName+"/" + beanName + "!" + viewClassName;// String jndi = "java:module/" + beanName + "!" + viewClassName;//out.println(jndi);TimeBeanLocal tb = (TimeBeanLocal)ctx.lookup(jndi);//TimeBeanLocal tb = (TimeBeanLocal)ctx.lookup("java:module/TimeBean!javaee.ejb.stateless.TimeBeanLocal");String str=tb.printTime();out.print("<br>通过JNDI调用本地接口EJB<br>"+str+"<br>");}catch(Exception e){System.out.println(e.getMessage());out.print("<br>本地接口调用失败!");}%>
</body>
</html>

程序里面的JNDI的路径可以是多种形式,如java:/app java:/module等。完成之后右键run on server 即可。此处的路径参考了

链接2,有不懂的地方仔细看看即可

这篇到这里,非常感谢那些有帮助的博客,thankyou。

对了,我室友的jsp在执行到context时会出现加载模块(module)失败,无法初始化上下文工厂,这个网上很少有这个错误,但是重写了EJB项目和web项目就可以正常使用了,不是代码的原因

  相关解决方案