web-dev-qa-db-ja.com

javaでHttpServletRequestから生の投稿データを取得する方法

Javaで投稿データを取得しようとしています。それは正しいことをするための最も簡単なことの1つであるように思えますか?つまり、HttpServletRequest.getParameterで正しく処理する必要がありますか?それでは、生の投稿データをどのように取得できますか?

HttpServletRequest get JSON POST data を見つけて、Kdeveloperのコードを使用してリクエストから投稿データをプルしました。動作しますが、キャッチがあります。データonce

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()メソッドを公開する必要があります-それが役立つとは誰も思いませんでしたか?

だから、常に正しい投稿データを返すようにこのメソッドを書くにはどうすればよいですか?

55
B T

リクエストの本文は、 HttpServletRequest#getInputStream() および #getReader() で利用できます。

_InputStream body = request.getInputStream();
// ...
_

一度しか読めないことに注意してください。クライアントはそれを複数回再送することはありません。 getParameter()などを呼び出すと、暗黙的に読み取られます。体をどこかに保管し、自分で処理する必要があります。

84
BalusC

IE text/plainとして投稿することを余儀なくされたため、getReaderを使用してパラメータを手動で解析する必要がありました。サーブレットは長いポーリングに使用されていたため、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\"}");
    }       
7
djabraham