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

一个小的调用本地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 stub
      		 Hashtable<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会话bean
                 HelloBeanRemote 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 stub
		Properties 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 stub
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter 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项目就可以正常使用了,不是代码的原因

发布了32 篇原创文章 · 获赞 5 · 访问量 4665

猜你喜欢

转载自blog.csdn.net/qq_38941327/article/details/89278301
今日推荐