2011-02-17 83 views
51

我试图在Java中获取发布数据。看起来应该是最简单的事情之一吧?我的意思是,HttpServletRequest.getParameter必须做到这一点?那么你怎么能得到原始的数据?如何从java中的HttpServletRequest中检索原始发布数据

我找到了HttpServletRequest get JSON POST data,并使用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()方法 - 没有人认为这会有用吗?

那么我该如何编写这种方法,使其始终返回正确的发布数据?

回答

81

请求正文由HttpServletRequest#getInputStream()#getReader()提供。

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

请注意,您只能阅读一次。客户端不会多次重新发送。调用getParameter()等将隐含地读取它。你必须将身体储存在某处并处理自己。

+3

所以你的回答是,有*没有办法做我想做的事情?它不是关于客户多次发送它。 HttpServletRequest清楚地将发布数据存储在某个地方(因为您总是可以多次获取发布参数)。我很欣赏这个答案,我只想完全理解你是在说“不可能”,还是只是在重新评估我已经发现的东西。 – 2011-02-17 00:23:12

6

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