从Java servlet中的POST请求获取请求有效负载

Fas*_*wan 99 java post servlets http

我有一个javascript库正在向我的Java servlet发送POST请求,但在该doPost方法中,我似乎无法获取请求有效负载的内容.在chrome Developer Tools中,所有内容都在headers选项卡的Request Payload部分中,内容就在那里,我知道doPost方法正在接收POST,但它只是空白.

对于HttpServletRequest 对象,我可以通过什么方式获取请求有效负载中的数据?

request.getParameter()request.getAttributes() 两者最终都没有数据

dav*_*cis 100

使用getReader()读取请求的主体

  • 如果您刚刚在过滤器中使用此帖子,然后发现其他任何内容都无法再次读取正文,则此帖子可能很有用!http://natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.html (23认同)
  • 没问题,有点隐藏那一个 (3认同)
  • @SgtPooki 随时为该评论添加一些推理,我的好先生! (3认同)

小智 63

String payloadRequest = getBody(request);
Run Code Online (Sandbox Code Playgroud)

使用这种方法

public static String getBody(HttpServletRequest request) throws IOException {

    String body = null;
    StringBuilder stringBuilder = new StringBuilder();
    BufferedReader bufferedReader = null;

    try {
        InputStream inputStream = request.getInputStream();
        if (inputStream != null) {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            char[] charBuffer = new char[128];
            int bytesRead = -1;
            while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                stringBuilder.append(charBuffer, 0, bytesRead);
            }
        } else {
            stringBuilder.append("");
        }
    } catch (IOException ex) {
        throw ex;
    } finally {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException ex) {
                throw ex;
            }
        }
    }

    body = stringBuilder.toString();
    return body;
}
Run Code Online (Sandbox Code Playgroud)

  • `new BufferedReader(new InputStreamReader(request.getInputStream()))`可以简化为已经缓冲的`request.getReader()`并保留请求编码. (9认同)
  • 考虑到`request.getInputStream()`不像`request.getReader()`那样遵守请求字符编码.所以这个例子使用默认的系统字符集. (6认同)
  • 我发现这个解决方案很有帮助,因为抛出了一个异常:`javax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has been called for this request` 当我调用 getReader() 作为阅读器已经打开的结果时. (2认同)

Fiz*_*han 49

您可以根据请求使用Buffer Reader来阅读

    // Read from request
    StringBuilder buffer = new StringBuilder();
    BufferedReader reader = request.getReader();
    String line;
    while ((line = reader.readLine()) != null) {
        buffer.append(line);
    }
    String data = buffer.toString()
Run Code Online (Sandbox Code Playgroud)


小智 38

Java 8流

String body = request.getReader().lines()
    .reduce("", (accumulator, actual) -> accumulator + actual);
Run Code Online (Sandbox Code Playgroud)

  • String body = request.getReader().lines().collect(Collectors.joining()); 也可以工作.Collectors.joining显然使用了引擎盖下的StringBuilder. (10认同)
  • 我认为应该request.getReader().lines().collect(join("\n"))来保留换行符. (3认同)
  • 你可以用 `String::concat` 替换 `(accumulator, actual) -> accumulator + actual`。 (2认同)

小智 18

使用Apache Commons IO,您可以在一行中完成此操作.

IOUtils.toString(request.getReader())
Run Code Online (Sandbox Code Playgroud)


Llo*_*ter 7

如果正文的内容是Java 8中的字符串,则可以执行以下操作:

String body = request.getReader().lines().collect(Collectors.joining());


小智 7

如果您能够以 JSON 格式发送有效负载,这是读取播放负载的最便捷方式:

示例数据类:

public class Person {
    String firstName;
    String lastName;
    // Getters and setters ...
}
Run Code Online (Sandbox Code Playgroud)

示例负载(请求正文):

{ "firstName" : "John", "lastName" : "Doe" }
Run Code Online (Sandbox Code Playgroud)

在 servlet 中读取有效负载的代码(需要 com.google.gson.*):

Person person = new Gson().fromJson(request.getReader(), Person.class);
Run Code Online (Sandbox Code Playgroud)

就这样。漂亮,简单,干净。不要忘记将内容类型标头设置为 application/json。