struts2的action都是pojo,这就带来了一个问题,pojo无法直接靠ejb3的注解注入相应的bean,并且如果通过jndi查找的话,也无法直接通过web的context进行查找,网上很多人用struts2-ejb-plugin这个插件来解决这些问题,但是这个插件目前只支持jboss和glassfish,对于weblogic,websphere等其它的服务器还不支持,还有很多人用struts的interceptor来做,但是个人感觉设计上有点混乱,所以自己想出了如下整合方式,绝对是可行的,但是在实际的应用中会不会出现问题还有待商讨,所以如果大家对此有什么意见的话,很希望可以和大家交流,方式如下:
通过listener或是filter来实现,pojo无法整合ejb的关键问题就是无法直接访问到容器的jndi,只有受管理的bean才可以,那么主要的解决思想就是通过受管理的bean访问过jndi context,然后以某种方式传给action,标准环境下的受管理bean大家很容易想到servlet, filter, listener,这里就用filter或是listener来做,我最后选择的是listener来实现的,当然filter也是完全可以的,我测试过,没有问题,方式也几乎相同:
/**
*@author 王硕
**/
//相应的已经注册的session bean
@EJB(name="DemoImpl", beanInterface=Demo.class)
public class EJBListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent event) {
HttpSession session = event.getSession();
try {
Context context = new InitialContext();
session.setAttribute("context", context);
} catch (Exception e) {
e.printStackTrace();
}
}
public void sessionDestroyed(HttpSessionEvent event) {
event.getSession().removeAttribute("context");
}
}
ok,这样的话,只要action打开session就可以获取jndi的context从而调用相应的session bean了:
/**
* @author 王硕
*/
public class DemoAction {
public String execute() {
try {
ActionContext ct = ActionContext.getContext();
Context context = (Context) ct.getSession().get("context");
Demo obj = (Demo) context.lookup("java:comp/env/DemoImpl");
obj.demo();
} catch (Exception e) {
e.printStackTrace();
}
return "success";
}
}
这个过程就是这样了,方式很简单,但是不知道把context放入到session会不会对应用的安全或性能造成影响,同样,filter的话也是用同样的方式获取到context之后放入session中然后同action来获取,过程是一样的,这样的话就可以不需要任务额外的配置或是插件完成struts2与ejb的整合了,当然,可以通过抽象的方式让这个过程变的更优雅,这里只是一个简单的过程,希望能对大家有帮助