【发布时间】:2016-04-26 15:03:44
【问题描述】:
问题: 我有一个在 Tomcat 实例中运行的 Java webapp,以及在同一个 Tomcat 实例中运行的第二个 JSP webapp JReport。我需要使用 JReport 生成报告,然后尽可能安全/合理地将结果发送到主 webapp。
我想使用依赖于 Tomcat 会话的加密 DB 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 服务器 => 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 => Servlet:
ServletContext context = getServletContext().getContext("/yawl_server");
RequestDispatcher rd = context.getRequestDispatcher("/reportsign");
rd.forward(request, response);
当我到达此代码时,上下文始终为空,尽管两个应用程序(假设?)在同一个虚拟主机中运行并且 getContext() 的参数与上下文的路径属性匹配。我做错了什么?
【问题讨论】: