我在以下情况下苦苦挣扎:
在当前运行于Tomcat 7.0.64上的Web应用程序中,我们设法借助自己的类CharArrayWriterResponse implementing HttpServletResponseWrapper
通过Java包含一个JSP页面。
这样做的原因是我们将生成的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
。在WebLogic中,不再调用
getWriter()
,这就是它不再起作用的原因。经过一些调试后,我发现在WebLogic中,如果我重写
getWriter()
,则仅调用getOutputStream()
而不是getWriter()
。在Weblogic上不会一次调用
getOutputStream()
,因此Tomcat和WebLogic的基础实现必须有所不同。问题是,使用
include()
时,我看不到在单独的流或其他内容中获得getWriter()
调用的响应并将其转换为String以用于构建包含HTML的最终JSON的可能性。有人已经解决了这个问题,并且可以提供一种可行的解决方案,以编程方式将JSP与WebLogic结合使用吗?
有谁知道实现我目标的另一种解决方案?
感谢您的建议。
解决方案
参见工作示例here
暗示
我发现Tomcat和新的Weblogic解决方案之间的区别:
对于后一种,不可能再将JSPF直接包含在Tomcat ojit_code中。
解决方案是将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
}
}
我使用了来自Apache commons-io的
WriterOutputStream
,因此必须将其包含在pom.xml中:<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>"}
关于java - WebLogic 12c中以编程方式包含RequestDispatcher的问题,包括JSP,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42440437/