[17.0.0.2 以及更新版本]

配置 Liberty Web 應用程式以重讀 POST 資料

您的 Web 應用程式可以藉由輸入串流、讀取器或剖析的參數,來重讀範圍中之要求的 POST 資料。請設定 Web 儲存器內容,以使用這個重讀行為。

開始之前

Java™ Servlet 規格容許 Web 應用程式藉由輸入串流、讀取器或剖析的參數,來讀取要求的 POST 資料。不過,Web 應用程式只能在要求範圍中使用這其中一種方法,來讀取 POST 資料。

在您設定 Web 儲存器內容時,您的 Web 應用程式可以多次重讀 POST 資料。不過,讀取器或輸入串流必須先關閉以完成讀取作業,之後才能啟動新的讀取作業。在關閉讀取器或輸入串流之前,不一定要全面讀取資料。可以完成資料的局部讀取。在剖析的參數方面,Web 儲存器會讀取整個 POST 資料,然後在剖析完所有參數之後,再關閉讀取作業。

您的應用程式可以對 POST 資料進行非阻斷式重讀。比方說,應用程式可以利用非同步讀取接聽器 (AsyncReadListener)、執行關閉,然後執行阻斷式讀取,來進行非阻斷式讀取。又比方說,此應用程式可以利用非同步讀取接聽器、執行關閉,然後利用新的非同步讀取接聽器執行第二次非阻斷式讀取,來進行非阻斷式讀取。

當您的應用程式利用非阻斷式讀取,來進行後續的 POST 資料讀取時,伺服器會先提供先前讀取的資料。如果先前完成的讀取並未完全讀取傳送到要求中的所有公佈資料,在應用程式讀取剩餘的 POST 資料時,新的讀取會執行阻斷。

關於這項作業

請將 Web 儲存器內容設為 true。然後執行可重讀 POST 資料的 Web 應用程式。會提供範例。

程序

  1. 啟用 POST 資料的重讀。

    當您在 server.xml 檔中將 enablemultireadofpostdata 自訂內容設為 true 時,會在伺服器層次設定該自訂內容。重讀行為會套用至伺服器上的所有 Web 應用程式。如果您希望重讀行為只套用至特定的 Web 應用程式,請在 web.xml 檔中,將 com.ibm.ws.webcontainer.SET_MULTI_READ_WEBAPP 環境定義參數設為 true。對於特定的 Web 應用程式,Web 應用程式層次的設定會置換伺服器層次的設定。

    enablemultireadofpostdata 自訂內容和 com.ibm.ws.webcontainer.SET_MULTI_READ_WEBAPP 環境定義參數兩者的預設值都是 false

    如果要在伺服器層次啟用此行為,請在 server.xml 檔中新增下列陳述式:
    <webContainer enablemultireadofpostdata="true" />
    如果要在 Web 應用程式層次啟用此行為,請在 web.xml 檔中新增下列 context-param 陳述式:
                    
    <context-param>                 
        <param-name>com.ibm.ws.webcontainer.SET_MULTI_READ_WEBAPP</param-name>                    
        <param-value>true</param-value>                
    </context-param>
  2. 執行可以重讀 POST 資料的 Web 應用程式。

範例

阻斷式讀取範例

下列的步驟和程式碼 Snippet 顯示應用程式如何利用 getInputStream () 方法、getParameter () 方法和 getReader () 方法,來重讀 POST 資料。不過,您可以在應用程式中隨意併用這些方法。
  1. 利用 getInputStream () 方法取得輸入串流。
  2. 讀取資料。
  3. 關閉輸入串流。
  4. 利用 getInputStream () 方法取得新的輸入串流。
  5. 讀取資料。
  6. 關閉輸入串流。
  7. 利用 getParameter () 方法取得參數。
  8. 利用 getReader () 方法取得讀取器。
  9. 讀取資料。
  10. 關閉讀取器。
  11. 利用 getParameter () 方法再次取得參數。
          java.io.InputStream in = request.getInputStream();
          byte[] inBytes = new byte[5];

          int readLen = in.read(inBytes);
          if (readLen > 0){
		
	     }              
          if (close)
                in.close();
	
	  java.io.InputStream in2 = request.getInputStream();
          byte[] inBytes = new byte[2048];

          for (int n; (n = in2.read(inBytes, 0, 2048)) != -1;) {
                readLen += n;
          }
          if (close)
                in2.close();

	  String param = request.getParameter("Test");
		
	  java.io.BufferedReader rdr = request.getReader();         
          StringBuffer inBuffer = new StringBuffer();
          char[] inChars = new char[1024];
          for (int n; (n = rdr.read(inChars,0,1024)) != -1;) {
             inBuffer.append(new String(inChars, 0, n));
          }
          rdr.close();

	  String param2 = request.getParameter("Test");

非阻斷式讀取範例

下列的步驟和程式碼 Snippet 顯示應用程式如何利用 getInputStream () 方法和 getParameter () 方法,來重讀 POST 資料。不過,您可以在應用程式中隨意併用這些方法。
  1. 利用 getInputStream () 方法取得輸入串流。
  2. 利用 setReadListener () 方法,從 Servlet 輸入串流取得接聽器。
  3. 讀取 onDataAvailable () 方法中的資料。
  4. 關閉輸入串流。

    在輸入串流關閉之後,不會對這個接聽器呼叫 onAllDataRead () 方法和 onError () 方法。

  5. 利用 getParameter () 方法取得參數。
  6. 利用 getInputStream () 方法取得新的輸入串流。
  7. 利用 setReadListener () 方法,從 Servlet 輸入串流取得新的接聽器。
  8. 讀取 onDataAvailable () 方法中的資料。
  9. 如果所有資料都已讀取,會對這個接聽器呼叫 onAllDataRead () 方法。
        java.io.InputStream input = request.getInputStream();
	RL1 = ((ServletInputStream) input).setReadListener(readListener);
	
	RL1
	onDataAvailable(){

		if (input.isReady()) {
                         Len = input.read(inBytes);                 
                }
		input.close();

	        String param = request.getParameter("Test");

       	        java.io.InputStream input = request.getInputStream();
		RL2 = ((ServletInputStream) input).setReadListener(readListener);
	}

        RL1 // onAllDataRead() or onError() will not be called for RL1, as the stream has been closed for RL1
     
        RL2
        onDataAvailable(){

		if (input.isReady()) {
                        Len = input.read(inBytes);                 
               }

	 }
	
	 RL2 // If all data read
	 onAllDataRead(){
	 	 AsncContext.complete();
	 }

指示主題類型的圖示 作業主題

檔名:twlp_reread_post.html