如何从Java中的HttpServletRequest检索原始POST数据?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (166)

我试图用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()和可用#getReader()

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

请注意,你只能阅读一次。客户端不会多次重新发送。调用getParameter()等也会隐含地读取它。

用户回答回答于

我们遇到了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\"}");
    }       

扫码关注云+社区