[英]JSP compilation to string or in memory bytearray with Tomcat/Websphere
我正在轉換為圖像和PDF輸出。 我需要一個由我們的應用程序JSP生成的輸入HTML文檔。 本質上,我需要將基於JSP的應用程序的最終輸出產品呈現給String或內存,然后使用該字符串進行其他處理。
有什么方法可以調用JSP渲染器來獲取通常輸出給用戶的最終HTML內容? 理想情況下,我正在尋找適用於websphere等多個應用服務器的東西。 但是特定於Tomcat的東西也會起作用。
還有其他幾種不同的方法,但我認為渲染JSP(可能包括子JSP)是最好的方法。
我寧願遠離的可選路徑。
我可以使用Socket API對頁面執行網絡請求,然后讀取從該特定頁面呈現的最終輸出。 這可能是下一個最佳選擇,但我們在多個服務器和JVM上工作,針對我需要的頁面會很復雜。
使用過濾器來獲取最終頁面輸出。 這很好,但我一直遇到過濾器和非法狀態異常的問題。 它似乎永遠不會像我需要的那樣100%工作。
看起來這應該很簡單。 JSP編譯器本質上只是一個用於解析輸入JSP文檔和子文檔然后輸出一些HTML內容的庫。 我想通過Java代碼調用該過程。 在服務器上,可能作為獨立的控制台應用程序。
這是一個徹頭徹尾的惱人問題,一個我不得不處理幾次,一個我從來沒有找到一個令人滿意的解決方案。
基本問題是servlet API在這里沒有幫助,所以你必須欺騙它。 我的解決方案是編寫HttpServletResponseWrapper的子類,它覆蓋getWriter()和getOutput()方法並將數據捕獲到緩沖區中。 然后,將您的請求轉發()到您要捕獲的JSP的URI,用您的包裝器響應替換原始響應。 然后,您從緩沖區中提取數據,對其進行操作,並將最終結果寫回原始響應。
這是我的代碼:
public class CapturingResponseWrapper extends HttpServletResponseWrapper {
private final OutputStream buffer;
private PrintWriter writer;
private ServletOutputStream outputStream;
public CapturingResponseWrapper(HttpServletResponse response, OutputStream buffer) {
super(response);
this.buffer = buffer;
}
@Override
public ServletOutputStream getOutputStream() {
if (outputStream == null) {
outputStream = new DelegatingServletOutputStream(buffer);
}
return outputStream;
}
@Override
public PrintWriter getWriter() {
if (writer == null) {
writer = new PrintWriter(buffer);
}
return writer;
}
@Override
public void flushBuffer() throws IOException {
if (writer != null) {
writer.flush();
}
if (outputStream != null) {
outputStream.flush();
}
}
}
使用它的代碼可以是這樣的:
HttpServletRequest originalRequest = ...
HttpServletResponse originalResponse = ...
ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
CapturingResponseWrapper responseWrapper = new CapturingResponseWrapper(originalResponse, bufferStream);
originalRequest.getRequestDispatcher("/my.jsp").forward(originalRequest, responseWrapper);
responseWrapper.flushBuffer();
byte[] buffer = bufferStream.toByteArray();
// now use the data
它非常難看,但它是我發現的最佳解決方案。 如果您想知道,包裝器響應必須包含原始響應,因為servlet規范說您在轉發時無法替換完全不同的請求或響應對象,您必須使用它們的原件或包裝版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.