簡體   English   中英

使用Tomcat / Websphere將JSP編譯到字符串或內存中

[英]JSP compilation to string or in memory bytearray with Tomcat/Websphere

我正在轉換為圖像和PDF輸出。 我需要一個由我們的應用程序JSP生成的輸入HTML文檔。 本質上,我需要將基於JSP的應用程序的最終輸出產品呈現給String或內存,然后使用該字符串進行其他處理。

有什么方法可以調用JSP渲染器來獲取通常輸出給用戶的最終HTML內容? 理想情況下,我正在尋找適用於websphere等多個應用服務器的東西。 但是特定於Tomcat的東西也會起作用。

還有其他幾種不同的方法,但我認為渲染JSP(可能包括子JSP)是最好的方法。

我寧願遠離的可選路徑。

  1. 我可以使用Socket API對頁面執行網絡請求,然后讀取從該特定頁面呈現的最終輸出。 這可能是下一個最佳選擇,但我們在多個服務器和JVM上工作,針對我需要的頁面會很復雜。

  2. 使用過濾器來獲取最終頁面輸出。 這很好,但我一直遇到過濾器和非法狀態異常的問題。 它似乎永遠不會像我需要的那樣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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM