【EJB系列】(二)——JBOSS7中EJB的远程调用和本地调用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010924834/article/details/51123010

导读

  因为JBOSS6,7版本在EJB的本地调用和远程调用的写法上不同于之前的版本。所以在本篇文章中将给出代码实例,仅供参考。

环境

MyEclipse10
JBOSS7

理论知识

远程调用(Remote Access)

过程

这里写图片描述

远程客户端

运行在跟EJB不同的机器或不同的JVM进程上
它可以是Web组件(如:JSP、Servlet)、应用客户端或其他的EJB
对客户端来说,EJB的位置时透明的。
为了创建一个能够被远程客户端访问的EJB,你必须用@Remote注解来定义这些EJB。

参数传递方式

传值


原因:

这里写图片描述

因为客户端和服务端属于不同的进程,所以内存空间不能共享。
客户端的User对象经过序列化和反序列化之后,变成了服务端的另一个User对象,当服务端对User对象的某个属性进行修改后,客户端的User对象的该属性是没有变化的。在后面的代码中我们会体现这一点。

注意事项

传递的参数如果是对象的话,需要实现序列化的接口implements Serializable

本地调用

过程

这里写图片描述

本地客户端

与EJB运行在同一个JVM进程上
它可以是Web组件(如:JSP、Servlet)或其他的EJB
对客户端来说,EJB的位置时透明的。
为了创建一个能够被远程客户端访问的EJB,你必须用@Local注解来定义这些EJB。

参数传递方式

传址


原因:传递的是对象的引用,不论是客户端或者是服务端对对象进行修改,都修改的是同一份。

代码

EJB的接口和实现

不同于之前的JBOSS版本,这里的EJB不能同时被声明为@Remote和@Local

项目目录

这里写图片描述

User.java(一定要实现Serializable接口)

package com.tgb.ejb;

import java.io.Serializable;

@SuppressWarnings("serial")
public class User implements Serializable {
    private String username;
    private int id;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

}

UserManagerRemote.java(远程调用接口)

package com.tgb.ejb;

public interface UserManagerRemote {
    public void addUser(User user);
}

UserManagerLocal.java(本地调用接口)

package com.tgb.ejb;

public interface UserManagerLocal {
    public void addUser(User user);
}

UserManagerBean.java(实现)

package com.tgb.ejb;


import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless
@Local(UserManagerLocal.class)
@Remote(UserManagerRemote.class)
public class UserManagerBean implements UserManagerRemote,UserManagerLocal {

    @Override
    public void addUser(User user) {
        System.out.println("user.username="+user.getUsername());
        user.setId(9);

    }

}

写完之后记得要部署到JBOSS,并运行JBOSS。

远程调用

常见一个JavaProject

这里写图片描述

具体步骤参考上一篇博文【EJB系列】(一)——JBOSS7中开发一个简单的EJB应用

结果

这里写图片描述

尽管服务端执行了setId(9),但是客户端getId()得到的仍是0。

本地调用

创建Web Project

编写并配置Servlet

UserServlet.java

package com.tgb.web;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;

import javax.naming.Context;
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;

import com.tgb.ejb.User;
import com.tgb.ejb.UserManagerLocal;


@SuppressWarnings("serial")
public class UserServlet extends HttpServlet {


    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {  

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");
        out.print("    This is ");
        out.print(this.getClass());
        out.println(", using the GET method");
        out.println("  </BODY>");
        out.println("</HTML>");

        out.flush();
        out.close();
    }



}

web.xml

<servlet>   
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>com.tgb.web.UserServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/servlet/UserServlet</url-pattern>
  </servlet-mapping>

部署项目访问Servlet

我的项目的访问连接时http://localhost:8091/ejb_03_webclient/servlet/UserServlet

项目的端口号要根据JBOSS的配置文件standalone.xml来

这里写图片描述

打包jar文件到lib目录下

将EJB项目“ejb_03”的四个java文件导出成jar包并且添加到此项目的WEB-INF的lib路径下

这里写图片描述

编写客户端

final Hashtable jndiProperties = new Hashtable();       
        jndiProperties.put(Context.URL_PKG_PREFIXES,"org.jboss.ejb.client.naming");//让JNDI API知道是由谁来管理我们用来查找JNDI 名字的命名空间的。
        Context context;
        try {
            context = new InitialContext(jndiProperties);
            //appName 和 moduleName分别就打包的格式而定
            //如果是.ear就是appName,其它的是moduleName(.jar,.war)
            final String appName = "";
            final String moduleName = "ejb_03_webclient";
            final String distinctName = "";
            //实现类名
            final String beanName = "UserManagerBean";
            System.out.println(beanName);
            //接口类名
            final String viewClassName = UserManagerLocal.class.getName();
            System.out.println(viewClassName);
            String jndi = "java:module/" + beanName + "!" + viewClassName;
            System.out.println(jndi);

            UserManagerLocal userManagerLocal;  
            userManagerLocal = (UserManagerLocal) context.lookup(jndi);         
            User user=new User();
            user.setUsername("许晨阳");            
            userManagerLocal.addUser(user);
            System.out.println("用户id:"+user.getId());
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

运行JBOSS

通过控制台我们可以看到我们部署后的EJB在JNDI中的路径,上面的代码中我们用的是其中的一个路径,剩余的这两个也可以:

java:global/ejb_03_webclient/UserManagerBean!com.tgb.ejb.UserManagerLocal
java:app/ejb_03_webclient/UserManagerBean!com.tgb.ejb.UserManagerLocal

这里写图片描述

这里写图片描述

我们看到最后输入的用户id为9,说明服务端的改变,用户端可以看到,说明操作的是同一个User对象。

总结

在这个过程中遇到的问题,包括:

1.本地调用时不需要引入jboss-client.jar,也不需要配置jboss-ejb-client.properties,但是要引入ejb_03.jar,而且要放到lib目录中,否则会报ClassDefNotFound,ClassCastException等错误。
2.另一个就是context.lookup时传递的名称。

远程调用的时候是:

String jndi = "ejb:" + appName + "/" + moduleName + "/"
                + distinctName + "/" + beanName + "!" + viewClassName;

本地调用的时候:

去掉前面的”ejb:”。换成“java:global”或“java:app”或“java:module”,但是要注意moduleName为ejb_03_webclient而不是“ejb_03”。具体路径的拼接,参考我们控制台输出的那三条路径,稍有不同。

参考

JNDI Reference
[AS7.1.1] EJB JNDI Lookup confusion: remote vs local

猜你喜欢

转载自blog.csdn.net/u010924834/article/details/51123010
EJB
今日推荐