簡體   English   中英

如何在java中從HttpServletRequest檢索原始帖子數據

[英]How to retrieve raw post data from HttpServletRequest in java

我正在嘗試用 Java 獲取帖子數據。 似乎這應該是最簡單的事情之一吧? 我的意思是, HttpServletRequest.getParameter 必須這樣做對嗎? 那么如何獲得原始的帖子數據呢?

我發現HttpServletRequest 獲取 JSON POST 數據並使用 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() 方法 - 沒有人認為這會有用嗎?

那么我該如何編寫這個方法,讓它始終返回正確的發布數據呢?

請求正文可通過HttpServletRequest#getInputStream()作為字節流使用:

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

或者作為HttpServletRequest#getReader()字符流:

Reader body = request.getReader();
// ...

請注意,您只能閱讀一次。 客戶端不會多次重新發送相同的請求。 調用getParameter()等也會隱式讀取它。 如果您稍后需要分解參數,則必須將主體存儲在某處並自行處理。

我們遇到過 IE 強制我們以 text/plain 形式發布的情況,因此我們不得不使用 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\"}");
    }       

這對我有用:(請注意需要 java 8)

String requestData = request.getReader().lines().collect(Collectors.joining());
UserJsonParser u = gson.fromJson(requestData, UserJsonParser.class);

UserJsonParse 是一個展示 gson 如何解析 json 共振峰的類。

班級是這樣的:

public class UserJsonParser {

    private String username;
    private String name;
    private String lastname;
    private String mail;
    private String pass1;
//then put setters and getters
}

解析的 json 字符串是這樣的:

$jsonData: {    "username": "testuser",    "pass1": "clave1234" }

其余值(郵件、姓氏、姓名)設置為空

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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