2011-02-17 47 views
51

我試圖在Java中獲取發佈數據。看起來應該是最簡單的事情之一吧?我的意思是,HttpServletRequest.getParameter必須做到這一點?那麼你怎麼能得到原始的數據?如何從java中的HttpServletRequest中檢索原始發佈數據

我找到了HttpServletRequest get JSON POST data,並使用Kdeveloper的代碼從請求中提取發佈的數據。它的工作,但一個趕上:我只能得到該發佈數據一次

繼承人我從Kdeveloper的代碼所做的方法:

public static String getPostData(HttpServletRequest req) { 
    StringBuilder sb = new StringBuilder(); 
    try { 
     BufferedReader reader = req.getReader(); 
     reader.mark(10000); 

     String line; 
     do { 
      line = reader.readLine(); 
      sb.append(line).append("\n"); 
     } while (line != null); 
     reader.reset(); 
     // do NOT close the reader here, or you won't be able to get the post data twice 
    } catch(IOException e) { 
     logger.warn("getPostData couldn't.. get the post data", e); // This has happened if the request's reader is closed  
    } 

    return sb.toString(); 
} 

以前我關在這個方法結束讀者,但引起的異常當方法運行不止一次上了同樣的要求。不關閉它,不會發生異常,但該方法返回一個空字符串。

老實說,應該有一個暴露的req.getPostData()方法 - 沒有人認爲這會有用嗎?

那麼我該如何編寫這種方法,使其始終返回正確的發佈數據?

回答

81

請求正文由HttpServletRequest#getInputStream()#getReader()提供。

InputStream body = request.getInputStream(); 
// ... 

請注意,您只能閱讀一次。客戶端不會多次重新發送。調用getParameter()等將隱含地讀取它。你必須將身體儲存在某處並處理自己。

+3

所以你的回答是,有*沒有辦法做我想做的事情?它不是關於客戶多次發送它。 HttpServletRequest清楚地將發佈數據存儲在某個地方(因爲您總是可以多次獲取發佈參數)。我很欣賞這個答案,我只想完全理解你是在說「不可能」,還是隻是在重新評估我已經發現的東西。 – 2011-02-17 00:23:12

6

我們遇到了IE強迫我們以文本/純文本格式發佈的情況,所以我們不得不使用getReader手動解析參數。該servlet被用於長輪詢,所以當AsyncContext :: dispatch在延遲之後執行時,它實際上是將空請求重新發布。

因此,我剛剛通過使用HttpServletRequest :: setAttribute將該帖子存儲在請求中。 getReader方法清空緩衝區,getParameter也會清空緩衝區,但會自動存儲參數。

String input = null; 

    // we have to store the string, which can only be read one time, because when the 
    // servlet awakens an AsyncContext, it reposts the request and returns here empty handed 
    if ((input = (String) request.getAttribute("com.xp.input")) == null) { 
     StringBuilder buffer = new StringBuilder(); 
     BufferedReader reader = request.getReader(); 

     String line; 
     while((line = reader.readLine()) != null){ 
      buffer.append(line); 
     } 
     // reqBytes = buffer.toString().getBytes(); 

     input = buffer.toString(); 
     request.setAttribute("com.xp.input", input); 
    } 

    if (input == null) { 
     response.setContentType("text/plain"); 
     PrintWriter out = response.getWriter(); 
     out.print("{\"act\":\"fail\",\"msg\":\"invalid\"}"); 
    }