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


113

我有一个javascript库,正在向我的Java servlet发送POST请求,但是在该doPost方法中,我似乎无法获取请求有效内容。在chrome开发人员工具中,所有内容都位于标题标签的“请求有效负载”部分中,并且内容在那里,而且我知道doPost方法正在接收POST,但它只是空白。

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

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


您需要指定哪个参数,例如,如果您体内有关键字,请使用String keyword = request.getParameter(“ keyword”);
justMe 2013年

看到JavaScript代码发送请求很有趣。显然是错误地组成了请求参数。
BalusC 2013年

@Razh好吧,是的,我知道,我只是在指定要尝试的方法。BalusC我正在使用resumable.js库处理拆分文件上传
Fasih Awan 2013年

4
如果我没有记错的话,请务必在从输入流读取之前不要使用request.getParameter(),否则将没有可用的数据(已读取)。
13年

Answers:


110

简单答案:
使用getReader()读取请求的正文

更多信息:
有两种方法可以读取体内数据:

  1. getReader()返回一个BufferedReader,它将允许您读取请求的正文。

  2. getInputStream()如果需要读取二进制数据,则返回ServletInputStream

从文档中注意:“ [两种方法都可以调用来读取主体,但不能同时读取两者。”


4
没问题,那个有点隐藏
-davidfrancis

25
如果您只是在过滤器中使用了此帖子,然后又发现其他任何东西都无法再次读取该正文,则该帖子可能会很有用! natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.html
JonnyRaa 2014年

这是一个非常糟糕的答案。
SgtPooki,

1
@SgtPooki随时添加一些评论理由,我的好先生!
大卫·弗朗西斯

@davidfrancis我不是在这里亲自判断您,但是:您没有提供任何上下文。.没有文档链接,没有示例。您对我评论的回复似乎比答案本身需要更多的努力。
SgtPooki

68
String payloadRequest = getBody(request);

使用这种方法

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;
}

6
考虑到request.getInputStream()不支持请求字符编码的request.getReader()情况。因此,此示例使用默认系统字符集。
Vadzim 2014年

9
new BufferedReader(new InputStreamReader(request.getInputStream()))可以简化为仅request.getReader()已缓冲,并保留请求编码。
Vadzim 2014年

1
我发现此解决方案很有帮助,因为抛出了异常:javax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has already been called for this request当阅读器已经打开时,我调用getReader()时。
本杰明·拉伯特

52

您可以使用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()

40

Java 8流

String body = request.getReader().lines()
    .reduce("", (accumulator, actual) -> accumulator + actual);

这很有趣,但是在字符串连接方面看起来效率很低!有什么办法可以改善吗?
davidfrancis '16

11
字符串正文= request.getReader()。lines()。collect(Collectors.joining()); 可能也可以。Collectors.joining显然在后台使用StringBuilder。
奥利弗·科尔

3
我认为它应该request.getReader()。lines()。collect(joining(“ \ n”))来保留换行符。
MichaelBöckling17年

在Java 8中,流将并行处理,因此需要添加顺序方法,否则它将合并错误的数据部分-字符串正文= request.getReader()。lines()。sequential()。reduce(System.lineSeparator(),(累加器,实际)->累加器+实际)
Jatin Bodarya

2
您可以替换(accumulator, actual) -> accumulator + actualString::concat
shmosel



5

如果您能够使用JSON发送有效负载,则这是读取播放负载的最便捷方法:

示例数据类:

public class Person {
    String firstName;
    String lastName;
    // Getters and setters ...
}

有效负载示例(请求主体):

{ "firstName" : "John", "lastName" : "Doe" }

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

Person person = new Gson().fromJson(request.getReader(), Person.class);

就这样。尼斯,容易和干净。不要忘记将content-type标头设置为application / json。


2

使用Java 8尝试使用资源:

    StringBuilder stringBuilder = new StringBuilder();
    try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
        char[] charBuffer = new char[1024];
        int bytesRead;
        while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
            stringBuilder.append(charBuffer, 0, bytesRead);
        }
    }

1

你只需要

request.getParameterMap()

用于获取POST和GET-参数。

该方法返回一个 Map<String,String[]>

您可以通过以下方式读取地图中的参数

Map<String, String[]> map = request.getParameterMap();
//Reading the Map
//Works for GET && POST Method
for(String paramName:map.keySet()) {
    String[] paramValues = map.get(paramName);

    //Get Values of Param Name
    for(String valueOfParam:paramValues) {
        //Output the Values
        System.out.println("Value of Param with Name "+paramName+": "+valueOfParam);
    }
}

2
注意:仅当使用编码时application/x-www-form-urlencoded,参数才可用;对于multipart/form-data,您显然需要通过直接访问主体部分request.getReader()并对其进行手动解析。
twonkeys
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.