来自HttpServlet的远程EJB

时间:2013-05-31 15:13:36

标签: java java-ee glassfish ejb openejb

我想从不同的EJB服务器调用远程EJB。我在OpenEJB上部署了远程EJB,然后我将从Glassfish HTTPServlet调用它们。我知道在本地EJB上我可以做@EJB注释,但我希望用户从Glassfish servlet“验证”远程OpenEJB服务器。

在OpenEJB上:

//OpenEJB server at 192.168.10.12
public class AdminManager {
    @RolesAllowed("admin")
    public void test() {
        System.out.println("Admin called this method");
    }
}

Glassfish Servlet

//Glassfish servlet at 192.168.10.10
public class AdminManage extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Properties p = new Properties();
            p.put("java.naming.factory.initial", "org.apache.openejb.client.RemoteInitialContextFactory");
            p.put("java.naming.provider.url", "ejbd://192.168.10.12:4201");
            // user and pass optional

      String userName = req.getSession().getAttribute("username");
      String password = req.getSession().getAttribute("password");
            p.put("java.naming.security.principal", userName );
            p.put("java.naming.security.credentials", "password );

            final InitialContext ctx = new InitialContext(p);

            final AdminManagerRemote myBean = (MyBean) ctx.lookup("AdminManagerRemote");
            try {
                myBean.test();
            } catch(Exception epx) {
                resp.sendRedirect(resp.encodeRedirectURL("/login"));
            }
    }
}

好的,这似乎是一个解决方案,但对我来说这不是“好”的解决方案。 每次对openejb进行身份验证都很糟糕,就像这样;

  String userName = req.getSession().getAttribute("username");
  String password = req.getSession().getAttribute("password");
  p.put("java.naming.security.principal", userName );
  p.put("java.naming.security.credentials", "password );

代码不干净。   我希望用户只进行一次身份验证并调用ejb方法。   有没有更好的解决方案?

我可以将Glassfish HTTP身份验证与远程openEJB身份验证相结合吗? 我的意思是当用户对Glassfish HTTP服务器进行身份验证时,我也希望openEJB进行身份验证。 这真让我生气。什么解决方案可以逃脱spagetti代码?

3 个答案:

答案 0 :(得分:0)

两个想法:

  1. 当用户登录Glassfish时对OpenEJB进行身份验证,将EJB存根存储在用户会话中并在以后重用。我担心你需要为serialization of the stub(所谓的句柄)实现一些EJB 2.x接口才能工作。

  2. 实现存储EJB存根的缓存。如果给定用户名/密码的存根在缓存中,则重复使用,如果不存在,则进行身份验证。缓存是一个静态对象,可以使用Guava的CacheBuilder创建它。这违反了规范(你不应该使用静态来在servlet之间共享信息),但由于它是一个缓存,所以这不是什么大问题。它甚至可以在集群中运行。

答案 1 :(得分:0)

您可以尝试引入服务定位器模式以消除代码中的冗余。隐藏底层细节&创建初始上下文,JNDI查找等的复杂性。

您可以缓存远程家庭界面EJBHome&然后在需要时重新使用它。

可以参考Core J2EE Patterns - Service Locator文档了解更多详情。

答案 2 :(得分:0)

Kerberos怎么样?有人知道kerberos解决方案吗? 使用TGS登录所有远程服务器。

但互联网上没有相关的样本。 而且很难用openldap安装kerberos。