2009-12-26 44 views
13

有什麼方法可以捕獲服務器端生成的動態內容,並將該文件或字符串對象與servlet相同。在服務器端捕獲生成的動態內容

我們可以使用JSP生成動態內容,但是我們無法訪問服務器端生成的動態內容。只要我們做了forward容器就會生成動態內容並將其發送給響應。

我需要訪問服務器端生成的動態內容。

任何幫助將不勝感激。

+1

你是什麼意思,動態內容?圖片 ?網頁 ?所有這些都是可能的,但你需要更具體。 – 2009-12-26 11:13:23

+0

我認爲Vishwanath建議在客戶端使用Javascript生成的'動態內容'因此無法被服務器訪問......除非有*另一種方式* – pavium 2009-12-26 11:31:42

+0

通過動態內容我的意思是我們使用web應用程序。在服務器端的內容,這將來自讓說數據庫哪個用戶以前存儲。 簡單一點,我只是想在運行時創建的網頁發送給webclient,而不是發送給webclient我需要它在服務器端的文件形式或說包含整個頁面的字符串對象。我可以寫入文件。 Regards, Vishwanath – Vishwanath 2009-12-26 12:23:29

回答

15

如果請求是冪等的(例如GET請求是),那麼只需使用java.net.URL即可獲得JSP輸出的InputStream。例如。

InputStream input = new URL("http://localhost/context/page.jsp").openStream(); 

如果請求不是冪等(如POST要求是),那麼你需要創建一個Filter它與PrintWriter與五種write()方法的自定義實現wrapsServletResponse其中複製輸出被覆蓋放入會話中存儲的某個緩衝區/構建器或本地磁盤文件系統中的臨時文件夾,以便後續請求中可以訪問它。例如。

package mypackage; 

import java.io.IOException; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.io.Writer; 

import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpServletResponseWrapper; 

public class CopyResponseFilter implements Filter { 

    public void init(FilterConfig config) throws ServletException { 
     // NOOP. 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
     throws IOException, ServletException 
    { 
     // Set character encoding for better world domination. 
     response.setCharacterEncoding("UTF-8"); 

     // Create copy writer. 
     HttpServletResponse httpResponse = (HttpServletResponse) response; 
     CopyWriter copyWriter = new CopyWriter(new OutputStreamWriter(
      httpResponse.getOutputStream(), httpResponse.getCharacterEncoding())); 

     // Filter request with response which is wrapped with new writer. 
     chain.doFilter(request, wrapResponse(httpResponse, copyWriter)); 

     // Store the copy writer afterwards in session so that it's available in next request. 
     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     httpRequest.getSession().setAttribute("copyWriter", copyWriter); 
    } 

    public void destroy() { 
     // NOOP. 
    } 

    private static HttpServletResponse wrapResponse 
     (final HttpServletResponse response, final PrintWriter writer) 
    { 
     return new HttpServletResponseWrapper(response) { 
      public PrintWriter getWriter() throws IOException { 
       return writer; 
      } 
     }; 
    } 

} 

class CopyWriter extends PrintWriter { 

    StringBuilder copy = new StringBuilder(); 

    public CopyWriter(Writer out) { 
     super(out); 
    } 

    public void write(int c) { 
     copy.append((char) c); // It is actually a char, not an int. 
     super.write(c); 
     super.flush(); 
    } 

    public void write(char[] chars) { 
     copy.append(chars); 
     super.write(chars); 
     super.flush(); 
    } 

    public void write(char[] chars, int offset, int length) { 
     copy.append(chars, offset, length); 
     super.write(chars, offset, length); 
     super.flush(); 
    } 

    public void write(String string) { 
     copy.append(string); 
     super.write(string); 
     super.flush(); 
    } 

    public void write(String string, int offset, int length) { 
     copy.append(string, offset, length); 
     super.write(string, offset, length); 
     super.flush(); 
    } 

    public String getCopy() { 
     return copy.toString(); 
    } 

} 

您可以訪問後續請求的任何servlet的最終輸出(請注意,您不能訪問它在當前請求的任何servlet,因爲它已經來不及用它做什麼)通過只是在會話訪問該CopyWriter

CopyWriter copyWriter = (CopyWriter) request.getSession().getAttribute("copyWriter"); 
String outputOfPreviousRequest = copyWriter.getCopy(); 

請注意,您應該在一個url-pattern該過濾器映射覆蓋感興趣的JSP頁面,因此不會對/*左右,否則會運行也包含在同一個JSP中的靜態文件(css,js,圖像等)。

另請注意,同一會話中的多個請求會相互覆蓋,您可以通過使用適當的url-pattern或以其他方式將其存儲在會話中來區分這些請求。口味爲Map<URL, CopyWriter>左右。

希望這會有所幫助。

+0

這是轟炸。我想我想要的確切答案。雖然我不熟悉JSP和過濾器。但我有辦法開始。我想巴魯在處理各種情況時已經給了我所需要的一切。謝謝Balu。 Regards, Vishwanath – Vishwanath 2009-12-26 16:32:37

0

您需要訪問服務器端的相應servlet,或者您可以編寫servlet。

Here是一個關於使用servlet的小教程。

0

重要的是要注意的是,JSP通過JSP編譯器編譯爲servlet(可能會生成Java代碼的一半低谷),所以您可以在JSP中使用servlet執行的任何操作。

關於此主題的一個注意事項:您應該瞭解MVC,一般而言,servlet充當控制器,JSP充當View,以及任何數據結構(Java bean等)充當模型。

爲了您的問題,您應該在servlet中生成內容/數據 - 這是您的對象表示的動態內容,執行您需要執行的任何處理,設置此數據以便JSP可以訪問它(例如request attribute ),在JSP中訪問並格式化客戶端。

要熟悉你應該檢查出Story of a Servlet: An Instant Tutorial,The Java™ EE 5 Tutorial on Web tier

+0

我知道MVC和servlets。準確地說,我知道servlet比JSP更多。你誤解了我的問題。我需要在服務器端動態生成的網頁。這就是我需要的,HTML Template http://html-tmpl-java.sourceforge.net/是一種方法。但是我想知道如何使用JSP和Servlet完成它的舊技術。 Regards, Vishwanath – Vishwanath 2009-12-26 12:31:04

+0

也許你應該檢查一下java模板語言:http://java-source.net/open-source/template-engines,我個人比較喜歡freemarker。 – 2009-12-26 13:46:35

+0

這是不錯的鏈接,你提供Zoran Regvart!感謝那 。 – Vishwanath 2009-12-26 14:08:39

2

據我瞭解你的目標,你想存儲生成的內容。雖然我想不出有什麼理由要這樣做,但這是可能的。

您可以使用Filter並創建您的HttpServletResponse的包裝,覆蓋一些write方法並捕獲將被輸出到瀏覽器的所有內容。

編輯:BalusC的答案是你需要的確切的擴展名,所以我不會詳細介紹。

+0

這是我需要的確切的東西,如果你繼續你的答案,我將非常感激。 我之所以問這個問題的原因是,我的組織使用HTML Template:java來做動態thingie。實際上是一個框架自己開發的HTML模板:java可以完成上面提到的事情,但是無法獲得如何使用JSP或servlet完成此操作。 Regards, Vishwanath – Vishwanath 2009-12-26 14:06:56

+0

您寧願重寫五個'write'方法,而不是'print(ln)'方法。 – BalusC 2009-12-26 15:13:44