【EJB系列】(二)——JBOSS7中EJB的远程调用和本地调用
来源:互联网 发布:finalcap唱词字幕软件 编辑:程序博客网 时间:2024/05/16 01:01
导读
因为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.UserManagerLocaljava: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
- 【EJB系列】(二)——JBOSS7中EJB的远程调用和本地调用
- 【EJB学习笔记】——远程调用和本地调用
- JBOSS系列(二) -EJB远程调用-JBOSS的配置
- EJB远程调用和本地调用
- 【EJB基础】远程调用和本地调用
- 【EJB系列】(一)——JBOSS7中开发一个简单的EJB应用
- EJB系列(二)——Session Bean 的开发和调用
- ejb的远程调用
- 详解JBOSS系列一(利用JNDI,EJB远程调用本地的Bean)
- EJB正确客户端调用(jboss6、jboss7)
- JBOSS系列(一) --EJB远程调用-客户端的配置
- Spring中调用远程EJB的配置
- websphere ejb 远程/本地调用总结
- websphere ejb 远程/本地调用总结
- weblogic——远程/近程调用EJB的方法总结
- 一步一步远程调用EJB
- EJB 远程调用问题
- JBoss7 创建客户端通过JNDI调用EJB
- 小工程——棋盘游戏:(人机交互)
- PHP PSR-4 Autoloader 自动加载(中文版)
- iOS UIWebView 加载网页、文件、 html
- 升级xcode7.3出现的问题
- 关于idea的一些操作技巧
- 【EJB系列】(二)——JBOSS7中EJB的远程调用和本地调用
- SQLite3.3.6 源代码文件结构
- 中英文维基百科语料上的Word2Vec实验
- 代码运行报错分析(更新中)
- 搭建自己的NuGet服务器以及在VS中自动生成NuGet包
- UVa 10001 - Garden of Eden
- 将唯一标示符保存在钥匙串中ps:udid是参数,需要传
- GeoServer数据库连接与配置
- Elipse 中 Android NDK 开发配置 Paths and Symbols中的Includes修改