欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合

程序员文章站 2022-03-24 21:44:01
...

本文是讲述使用struts2-ejb3-plugin这个插件将Struts2与EJB3.0进行整合开发。
你可以从Apache的Struts2的Plugin列表了解它: http://cwiki.apache.org/S2PLUGINS/home.html

也可直接进入主页了解它:
http://cwiki.apache.org/S2PLUGINS/struts2-ejb3-plugin.html
或者从该Google代码:
http://code.google.com/p/struts2-ejb3-plugin/
        Struts2是时下比较流行的JAVA EE框架,而EJB为JAVA企业平台标准规范并且是JAVA EE体系的核心技术,不过前几年由于EJB2.1的烦琐以及spring、hibernate等轻量级框架的推广流行,EJB2.1大有被取代的趋势。在这种情况下,吸取了spring、hibernate等框架的优点的EJB3.0也就顺理成章的诞生,不过经过了漫长的发布过程后,貌似天下已经是spring、hibernate等轻量级框架的了,在中国国内更是满国尽是SSH(我自己也觉得说得夸张了点^_^)。EJB3.0貌似在中国的关注度并不是很高,也好象并没有多少公司多少人使用它,这也造成了EJB3.0的中文资料比较少,而与像Struts2这样的优秀的框架整合的资料就更少了。曾经在一个项目中决定使用Struts2与EJB3.0,在Struts2的Action与Interceptor里使用context.lookup来查找EJB组件是多么的痛苦。四处寻找好的整合方案,却空手而回。Apache的Struts2的Plugin列表里有两个EJB3.0的Plugin,可以通过注解完成整合,不过因为引入了第三方类库与必须是写死的引用路径而最终放弃了。最后,写了一种模拟应用服务器的规则以及EJB组件生命周期的Plugin,struts2-ejb3-plugin就是这个Plugin。

 

上面废话了这么多-。-下面进入正题。

插件的安装:

struts2-ejb3-plugin的安装比较简单,拖Struts2优秀的Plugin机制的福,只需要将struts2-ejb3-plugin.jar放到 /WEB-INF/lib 目录中就可以了。 除了plugin本身的配置以外,还需要在 classpath 下创建名为 jndi.properties 的资源文件用做 jndi配置
,plugin 中使用到的jndi查找依赖于该配置。

 

代码示例:

 

先是几个SessionBean

 

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. @Remote  
  2. public interface DemoRemote extends Serializable {   
  3.   
  4.     void remoteMethod();   
  5. }  
@Remote
public interface DemoRemote extends Serializable {

	void remoteMethod();
}

  

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. @Local  
  2. public interface DemoLocal {   
  3.   
  4.     void localMethod();   
  5. }  
@Local
public interface DemoLocal {

	void localMethod();
}

 

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. @Stateless(name = "ejb/demo1")   
  2. public class DemoBean implements DemoLocal, DemoRemote {   
  3.   
  4.     private static final long serialVersionUID = -779739898907524857L;   
  5.   
  6.     public void localMethod() {   
  7.         System.out.println("DemoBean本地方法。");   
  8.     }   
  9.   
  10.     public void remoteMethod() {   
  11.         System.out.println("DemoBean远程方法。");   
  12.     }   
  13. }  
@Stateless(name = "ejb/demo1")
public class DemoBean implements DemoLocal, DemoRemote {

	private static final long serialVersionUID = -779739898907524857L;

	public void localMethod() {
		System.out.println("DemoBean本地方法。");
	}

	public void remoteMethod() {
		System.out.println("DemoBean远程方法。");
	}
}

 

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. @Stateless(name = "ejb/demo2")   
  2. public class DemoBean2 implements DemoLocal {   
  3.   
  4.     public void localMethod() {   
  5.         System.out.println("DemoBean2本地方法。");   
  6.     }   
  7. }  
@Stateless(name = "ejb/demo2")
public class DemoBean2 implements DemoLocal {

	public void localMethod() {
		System.out.println("DemoBean2本地方法。");
	}
}

 

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. @Remote  
  2. public interface DemoMethodInjectRemote extends Serializable{   
  3.   
  4.     void method();   
  5. }  
@Remote
public interface DemoMethodInjectRemote extends Serializable{

	void method();
}

 

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. @Local  
  2. public interface DemoMethodInjectLocal {   
  3.   
  4.     void method();   
  5. }  
@Local
public interface DemoMethodInjectLocal {

	void method();
}

 

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. @Stateless  
  2. public class DemoMethodInjectBean implements DemoMethodInjectLocal,   
  3.         DemoMethodInjectRemote {   
  4.   
  5.     private static final long serialVersionUID = 806301363823340506L;   
  6.   
  7.     public void method() {   
  8.         System.out.println("DemoMethodInjectBean");   
  9.     }   
  10. }  
@Stateless
public class DemoMethodInjectBean implements DemoMethodInjectLocal,
		DemoMethodInjectRemote {

	private static final long serialVersionUID = 806301363823340506L;

	public void method() {
		System.out.println("DemoMethodInjectBean");
	}
}

 

 

下面是Interceptor

 
Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. public class DemoInterceptor1 {   
  2.   
  3.     @AroundInvoke  
  4.     public Object interceptorMethod(InvocationContext invocationContext) throws Exception {   
  5.         System.out.println("拦截器1。");   
  6.         return invocationContext.proceed();   
  7.     }   
  8. }  
public class DemoInterceptor1 {

	@AroundInvoke
	public Object interceptorMethod(InvocationContext invocationContext) throws Exception {
		System.out.println("拦截器1。");
		return invocationContext.proceed();
	}
}

  

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. public class DemoInterceptor2 {   
  2.   
  3.     @AroundInvoke  
  4.     public Object interceptorMethod(InvocationContext invocationContext) throws Exception {   
  5.         System.out.println("拦截器2。");   
  6.         return invocationContext.proceed();   
  7.     }   
  8. }  
public class DemoInterceptor2 {

	@AroundInvoke
	public Object interceptorMethod(InvocationContext invocationContext) throws Exception {
		System.out.println("拦截器2。");
		return invocationContext.proceed();
	}
}

 

 

SessionBean 与 Interceptor 都会在执行到它们的时候打印出自己的信息。

 

 

 

下面是本文的重点,Struts2的Action

 

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. @Interceptors(DemoInterceptor1.class)   
  2. public class DemoAction extends ActionSupport {   
  3.   
  4.     private static final long serialVersionUID = -472366623817152071L;   
  5.   
  6.     @EJB  
  7.     private DemoRemote demoRemote;   
  8.   
  9.     // /////   
  10.     // 为 glassfish2时,要将本地接口的注入注释掉,glassfish不支持本地接口在web层调用,如果不注释掉会在部署时报错。   
  11.     @EJB  
  12.     private DemoLocal demoLocal;   
  13.     // /////   
  14.   
  15.     private DemoMethodInjectRemote demoMethodInjectRemote;   
  16.   
  17.     @EJB(beanName = "ejb/demo1")   
  18.     private DemoRemote demo1;   
  19.   
  20.     @EJB(beanName = "ejb/demo1")   
  21.     private DemoRemote demo2;   
  22.   
  23.     @EJB  
  24.     public void setDemoMethodInjectRemote(   
  25.             DemoMethodInjectRemote demoMethodInjectRemote) {   
  26.         this.demoMethodInjectRemote = demoMethodInjectRemote;   
  27.     }   
  28.   
  29.     @PostConstruct  
  30.     @Interceptors(DemoInterceptor2.class)   
  31.     @ExcludeClassInterceptors()   
  32.     public void init() {   
  33.         System.out.println("初始化。");   
  34.     }   
  35.   
  36.     @Interceptors( { DemoInterceptor2.class, DemoInterceptor1.class })   
  37.     @Override  
  38.     public String execute() throws Exception {   
  39.         demoRemote.remoteMethod();   
  40.         demoLocal.localMethod();   
  41.         demoMethodInjectRemote.method();   
  42.         demo1.remoteMethod();   
  43.         demo2.remoteMethod();   
  44.         return SUCCESS;   
  45.     }   
  46.   
  47. }  
@Interceptors(DemoInterceptor1.class)
public class DemoAction extends ActionSupport {

	private static final long serialVersionUID = -472366623817152071L;

	@EJB
	private DemoRemote demoRemote;

	// /////
	// 为 glassfish2时,要将本地接口的注入注释掉,glassfish不支持本地接口在web层调用,如果不注释掉会在部署时报错。
	@EJB
	private DemoLocal demoLocal;
	// /////

	private DemoMethodInjectRemote demoMethodInjectRemote;

	@EJB(beanName = "ejb/demo1")
	private DemoRemote demo1;

	@EJB(beanName = "ejb/demo1")
	private DemoRemote demo2;

	@EJB
	public void setDemoMethodInjectRemote(
			DemoMethodInjectRemote demoMethodInjectRemote) {
		this.demoMethodInjectRemote = demoMethodInjectRemote;
	}

	@PostConstruct
	@Interceptors(DemoInterceptor2.class)
	@ExcludeClassInterceptors()
	public void init() {
		System.out.println("初始化。");
	}

	@Interceptors( { DemoInterceptor2.class, DemoInterceptor1.class })
	@Override
	public String execute() throws Exception {
		demoRemote.remoteMethod();
		demoLocal.localMethod();
		demoMethodInjectRemote.method();
		demo1.remoteMethod();
		demo2.remoteMethod();
		return SUCCESS;
	}

}

 

 Action中通过EJB的注解注入前面的SessionBean,并且支持除全局默认拦截器注解外的拦截器相关注解。对于生命周期注解,目前只支持@PostConstruct。struts2-ejb3-plugin的好处是通过模拟应用服务器规则与模拟EJB组件生命周期完成整合,无须引入第三方类库。

 

对于Struts2自带的拦截器,struts2-ejb3-plugin也能够像Action一样正常工作。在Action的execute(或者自定义的名称)方法中同时使用struts2的Interceptor和@Interceptors 时,@Interceptors会在Interceptor之前开始,在Interceptor之后结束。

 

下面看个 Struts2的Interceptor

 

 
 

 

 

 
Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
  1. public class DemoStrutsInterceptor implements Interceptor {   
  2.   
  3.     private static final long serialVersionUID = 3525334943511726314L;   
  4.   
  5.     @EJB  
  6.     private DemoRemote demoRemote;   
  7.        
  8.     public void destroy() {   
  9.   
  10.     }   
  11.   
  12.     public void init() {   
  13.         System.out.println("struts拦截器初始化。");   
  14.     }   
  15.        
  16.     @PostConstruct  
  17.     @Interceptors(DemoInterceptor1.class)   
  18.     public void pluginInit(){   
  19.         System.out.println("struts2-ejb3-plugin初始化。");   
  20.     }   
  21.   
  22.     @Interceptors(DemoInterceptor2.class)   
  23.     public String intercept(ActionInvocation arg0) throws Exception {   
  24.         System.out.println("Struts拦截器");   
  25.         demoRemote.remoteMethod();   
  26.         return arg0.invoke();   
  27.     }   
  28.   
  29. }  
public class DemoStrutsInterceptor implements Interceptor {

	private static final long serialVersionUID = 3525334943511726314L;

	@EJB
	private DemoRemote demoRemote;
	
	public void destroy() {

	}

	public void init() {
		System.out.println("struts拦截器初始化。");
	}
	
	@PostConstruct
	@Interceptors(DemoInterceptor1.class)
	public void pluginInit(){
		System.out.println("struts2-ejb3-plugin初始化。");
	}

	@Interceptors(DemoInterceptor2.class)
	public String intercept(ActionInvocation arg0) throws Exception {
		System.out.println("Struts拦截器");
		demoRemote.remoteMethod();
		return arg0.invoke();
	}

}

 可以看出,对Struts2的拦截器不仅可以使用注入,还可以对它使用生命周期以及拦截器的注解(拦截器的拦截器。。。恩,有点绞。。^_^)。

 

 

 

 

 

 

对配置文件的一些说明

plugin的默认配置,该配置为 cn/agrael/struts/plugin/ejb3/default-struts-ejb3-plugin.properties中的配置。配置信息如下:

 

Java代码 [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss  [转]通过struts2-ejb3-plugin把Struts2与EJB3.0整合
            
    
    博客分类: J2EE开发技术指南EJB3开发应用 struts2ejb3glassfishjboss 
#ENC的默认名
ENCPath=java:comp/env/
#应用服务器的具体实现类,该类是 cn.agrael.struts.plugin.ejb3.ApplicationServer的实现类
ejbContainer=cn.agrael.struts.plugin.ejb3.JbossApplicationServer
#是否解析@Resource的标志 true 为解析,false 为不解析
isParseResource=false
#是否解析@EJB的标志 true 为解析,false 为不解析
isParseEJB=true
#ear的路径名,如果没有则为空字符串
earFileBaseName=
#为远程Bean时的JNDI路径
remote=remote
#为本地Bean时的JNDI路径
local=local

 如果要修改默认的配置,需要在 classpath 下建立为 struts-ejb3-plugin.properties
的资源文件覆盖默认的配置。

 

目前的版本暂时不支持@PreDestroy。 现阶段只有 jboss与glassfish2.x 应用服务器的实现,在以后的版本中会陆续增加如 weblogic 等应用服务器的实现。如果现在需要 jboss与glassfish2.x之外的实现,可实现 cn.agrael.struts.plugin.ejb3.ApplicationServer 接口或者继承cn.agrael.struts.plugin.ejb3.AbstractApplicationServer类,并使用 struts-ejb3-plugin.properties 修改 ejbContainer 为实现类。

 

关于Struts2与EJB3.0的整合就写到这里了,附件里有完整的DEMO,因为比较简单,所以没写注释,希望大家见谅。

因为本人经验及水平有限,如有疏漏或者是错误的地方,希望大家多多拍砖^_^。