我正在努力应对以下情况:
在当前运行于Tomcat7.0.64上的Web应用程序中,我们借助自己的class设法通过Java包含一个JSP页面CharArrayWriterResponseimplementing HttpServletResponseWrapper。
CharArrayWriterResponseimplementing HttpServletResponseWrapper
这样做的原因是,我们将生成的HTML包装到AJAX响应所需的JSON中。
依存关系:
<dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
代码示例:
// somewhere in servlet doPost()/doGet() try (PrintWriter out = response.getWriter()) { out.println(getJspAsJson(request, response)); } private static String getJspAsJson(HttpServletRequest request, HttpServletResponse response) { String html = getHtmlByJSP(request, response, "WEB-INF/path/to/existing.jsp"); Gson gson = new GsonBuilder().disableHtmlEscaping().create(); return "{\"results\":" + gson.toJson(html) + "}"; } public static String getHtmlByJSP(HttpServletRequest request, HttpServletResponse response, String jsp) { CharArrayWriterResponse customResponse = new CharArrayWriterResponse(response); request.getRequestDispatcher(jsp).include(request, customResponse); return customResponse.getOutput(); } public class CharArrayWriterResponse extends HttpServletResponseWrapper { private final CharArrayWriter charArray = new CharArrayWriter(); public CharArrayWriterResponse(HttpServletResponse response) { super(response); } @Override public PrintWriter getWriter() throws IOException { // this is called ONLY in tomcat return new PrintWriter(charArray); } public String getOutput() { return charArray.toString(); } @Override public ServletOutputStream getOutputStream() throws IOException { // this is called ONLY in WebLogic return null; // don't know how to handle it } }
提示:在上述代码示例中,我没有考虑异常处理。
我必须将此应用程序迁移到WebLogic(12.2.1),但此解决方案不再起作用。
到目前为止,我发现了什么:
在Tomcat中,调用了我request.getRequestDispatcher(jsp).include()上面的示例示例之后。getWriter()``CharArrayWriterResponse
request.getRequestDispatcher(jsp).include()
getWriter()``CharArrayWriterResponse
WebLogic getWriter()中不再被调用,这就是它不再起作用的原因。
getWriter()
经过一些调试后,我发现在WebLogic中,如果我重写它,则getWriter()仅getOutputStream()调用它。 getWriter()不会在Weblogic上调用一次,因此Tomcat和WebLogic的基础实现必须有所不同。
getOutputStream()
问题在于,getOutputStream()我看不到include()在单独的流或其他内容中获得调用响应并将其转换为String以用于构建包含HTML的最终JSON的可能性。
include()
有人已经解决了这个问题,并且可以提供一种可行的解决方案,以编程方式将JSP与WebLogic结合使用吗?
有谁知道实现我目标的另一种解决方案?
感谢您的建议。
我发现Tomcat和新的Weblogic解决方案之间的区别:对于后者,不可能再将Tomcat直接包含JSPF getWriter()。
解决方案是将JSPF包装在JSP文件中。
我这样做:
@Override public ServletOutputStream getOutputStream() throws IOException { // this is called ONLY in WebLogic // created a custom outputstream that wraps your charArray return new CustomOutputStream(this.charArray); } // custom outputstream to wrap charArray writer class CustomOutputStream extends ServletOutputStream { private WriterOutputStream out; public CustomOutputStream(CharArrayWriter writer) { // WriterOutputStream has a constructor without charset but it's deprecated, so change the UTF-8 charset to the one you use, if needed this.out = new WriterOutputStream(writer, "UTF-8"); } @Override public boolean isReady() { return true; } @Override public void setWriteListener(WriteListener writeListener) { } @Override public void write(int b) throws IOException { this.out.write(b); this.out.flush(); // it doesn't work without flushing } }
我使用的WriterOutputStream是Apache Commons-io,因此必须在pom.xml中添加它:
WriterOutputStream
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency>
我不知道您的jsp文件中包含什么,但是我已经用一个简单的文件进行了测试,我相信它可以工作。我的jsp文件:
<b>Hello world</b> <p>testing</p> <ul>test <li>item</li> <li>item2</li> </ul>
输出(在浏览器中访问servlet时):
{"results":"<b>Hello world</b>\n\n<p>testing</p>\n\n<ul>test\n<li>item</li>\n<li>item2</li>\n</ul>"}