如何在同一个EAR /应用程序中动态获取另一个Web模块的上下文根

时间:2012-06-09 05:59:36

标签: java java-ee servlets websphere

我的应用程序包含两个Web模块,如下所示:

<module>
    <web>
        <web-uri>myWeb1.war</web-uri>
        <context-root>/web1</context-root>
    </web>
</module>
<module>
    <web>
        <web-uri>myWeb2.war</web-uri>
        <context-root>/web2</context-root>
    </web>
</module>

,我需要将请求从“web1”模块转发到“web2”,如下所示。

RequestDispatcher rd = getServletContext().getContext("/web2").getRequestDispatcher("/servlets/actReq");
        rd.forward(request, response);

问题是,是否可以检索上下文根名称:“web2”,在代码中对此进行编码。我不想硬编码上下文根的原因是因为在部署EAR包期间这可能会发生变化。

提前致谢。

1 个答案:

答案 0 :(得分:1)

我不知道如何直接这样做。这种直接的应用程序到应用程序,甚至servlet到servlet的通信都被规范轻轻阻止。

您可以做的是为每个标记为load-on-startup的应用程序添加一个简单的servlet,并在其init方法中捕获上下文路径并将其存储在某处。您可以注入一个收集上下文路径的EJB。像(非常粗略的草图!):

@Singleton
public class ContextPaths extends HashMap<String, String> {}

public class RegisterContextPath extends HttpServlet {
    @EJB
    private ContextPaths contextPaths;

    public void init() {
        String contextPath = getServletContext().getContextPath();
        contextPaths.put("myWeb1", contextPath);
    }
}

然后,可以向EJB注入想要执行调度的servlet,并在其中进行查找。

请注意,您无法使用CDI @ApplicationScoped,因为init()期间应用程序范围无效(我认为)。

您可以使用某种生命周期监听器来进行注册,而不是使用servlet。

你也可能对地图密钥有点聪明 - 使用getServletContextName()然后依靠在web.xml中设置的display-name?使用init参数?理想情况下,您可以在所有Web应用程序中使用一个类,只是配置不同。