java - 从一个 Tomcat 实例中的另一个 webapp 调用方法

标签 java jsp tomcat

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

我想使用依赖于 Tomcat session 的加密数据库 ID,但我愿意使用未加密的 ID 或临时 token 。一些快速研究(阅读:谷歌搜索)告诉我,这应该可以通过 Tomcat 跨上下文实现。

可能的解决方案: This webpage给出了一些使用 Spring 框架在两个 Web 应用程序之间调用方法的简要说明。据我所知,我的 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是被调用的app;jreport是调用的app):

Tomcat 服务器 => server.xml(可能渲染 yawl_server => 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 => 小服务程序:

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

当我到达这段代码时,上下文始终为空,尽管这两个应用程序(据说?)在同一虚拟主机中运行并且 getContext() 的参数与上下文的路径属性相匹配。我做错了什么?

最佳答案

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

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

    URLConnection conn = new URL("your other web app servlet url").openConnection(); //使用 conn 传递数据。然后在另一边,您可以有一个 servlet 来接收这些调用。

  2. 使用 JMS 进行异步通信。
  3. 使用网络服务(SOAP 或 REST)
  4. 通过使用 RMI
  5. 通过在应用程序之间共享数据库。所以一个写入表,另一个从该表读取 通过共享文件系统文件...一个写入文件,另一个从文件读取。
  6. 使用套接字连接。

关于java - 从一个 Tomcat 实例中的另一个 webapp 调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36868771/

相关文章:

java - 如何将值从 servlet 传递到 html 页面

tomcat - 嵌入式与独立 Tomcat ( HTTP ) 服务器

java - 修剪月份正则表达式的名称

java - JUnit/Mockito : throwing an exception in a new thread

java - android textedit 从退格键上的字符串中删除子字符串

在 JSP 中获取数组长度时出现 java.lang.NumberFormatException

java - org.apache.tiles.template.NoSuchAttributeException : Attribute 'body' not found

java - 将项目一异常(exception)纳入项目二

java - 在单个服务器中部署多个 Spring Boot Web 应用程序

javascript - Tomcat CORS : Preflight successful, 但实际请求因 403 禁止而失败