在Tomcat实例

时间:2016-04-26 15:03:45

标签: java jsp tomcat

问题: 我有一个在Tomcat实例中运行的Java webapp,以及在同一个Tomcat实例中运行的第二个JSP webapp,JReport。我需要使用JReport生成报告,然后尽可能安全/合理地将结果发送到主Web应用程序。

我想使用依赖于Tomcat会话的加密数据库ID,但我会选择未加密的ID或临时令牌。一些快速研究(阅读:谷歌搜索)告诉我,这应该可以通过Tomcat交叉上下文来实现。

可能的解决方案: This webpage提供了一些使用Spring框架在两个webapps之间调用方法的简要说明。我的webapp和JReport都没有使用我所知道的Spring,因此我无法弄清楚如何将代码示例应用到我的代码中。

代码:此代码改编自上面链接的页面上的示例。有两个地方我不知道要在函数调用中放入什么参数:

private void sendPdf(HttpServletRequest request, String custCode, int reportId, int documentId, byte[] data) {
    ServletContext srcServletContext = request.getSession().getServletContext();

    // Where does this parameter come from???
    ServletContext targetServletContext = srcServletContext.getContext("/Bar");

    //save the class loader which loaded the 'Foo' application in a variable
    ClassLoader currentClassLoader = Thread.currentThread().
    getContextClassLoader();

    try {
        // What attribute name to put here???
        Object object = targetServletContext.getAttribute
        ("org.springframework.web.servlet.FrameworkServlet.CONTEXT.bar");

        // Get the class loader for Yawl and set it as the current class loader
        ClassLoader targetServiceClassLoader = object.getClass().getClassLoader();
        Thread.currentThread().setContextClassLoader(targetServiceClassLoader);

        // Get the ReportSigner class and its static method
        Class<?> reportSignerClass = (Class<?>) targetServiceClassLoader.loadClass("com.procentive.yawl.logic.report.ReportSigner");
        Method targetMethod = reportSignerClass.getMethod("addReportPdf", String.class, Integer.class, Integer.class, byte[].class);

        // Invoke the static method on ReportSigner
        targetMethod.invoke(null, custCode, reportId, documentId, data);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // Revert to original class loader
        Thread.currentThread().setContextClassLoader(currentClassLoader);
    }
}

这是我的应用程序的context.xml(也改编自同一页面):

<?xml version="1.0" encoding="UTF-8"?>
<context cookies="false" override="true" crossContext="true">
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
</context>

问题:我在第5行放入getContext()的上下文名称是什么?我在第14行放入getAttribute()的属性名是什么?这是进行webapp通信的正确方法吗?或者完全做其他事情会更好/更容易/更安全吗?

更新

在让JReport运行新代码遇到一些困难之后,我终于能够对此进行测试了。我从另一个问题中跟随this answer的示例,并尝试使用servlet和RequestDispatcher。

相关代码(yawl_server是应用程序被调用; jreport是执行调用的应用程序):

Tomcat服务器=&gt; server.xml(可能渲染yawl_server =&gt; context.xml多余?):

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
    <Context docBase="yawl_server" path="/yawl_server" crossContext="true" reloadable="true" source="org.eclipse.jst.jee.server:yawl_server"/>
</Host>

jreport =&gt; Servlet的:

ServletContext context = getServletContext().getContext("/yawl_server");
RequestDispatcher rd = context.getRequestDispatcher("/reportsign");
rd.forward(request, response);

当我到达此代码时,尽管两个应用程序(假设是?)在同一个虚拟主机中运行,并且getContext()的参数与上下文的path属性匹配,但上下文始终为null。我做错了什么?

2 个答案:

答案 0 :(得分:4)

我有这样的问题,我找到了解决方法 您可以通过多种方式传递数据:

  1. 通过您的应用发出http请求:

    URLConnection conn = new URL("your other web app servlet url").openConnection(); // pass data using conn. Then on other side you can have a servlet that will receive these calls.

  2. 使用JMS进行异步通信。
  3. 使用Webservice(SOAP或REST)
  4. 使用RMI
  5. 通过在应用之间共享数据库。因此,一个写入表,另一个读取该表 通过共享文件系统文件...一个文件向文件写入另一个文件读取。
  6. 使用套接字连接。

答案 1 :(得分:2)

我使用的解决方案是在使用配置了crosscontext =&#34; true&#34; 两个上下文配置我的server.xml后,将请求转发到我的应用程序中的新servlet。 / p>

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
    <Context docBase="yawl_server" path="/yawl_server" crossContext="true" reloadable="true" source="org.eclipse.jst.jee.server:yawl_server"/>
    <Context path="/jreport" crossContext="true"></Context>
</Host>

转发请求时,我想添加另一个参数,所以我不得不将其添加为GET参数:

ServletContext context = getServletContext().getContext("/yawl_server");
RequestDispatcher rd = context.getRequestDispatcher("/reportsign?reportFilename=" + filename);
rd.forward(request, response);