在Spring MVC中写入文件请求

我希望能够将整个请求写入Spring MVC控制器中的文件。

我尝试了以下内容,但即使我正在使用大量参数发出POST请求,该文件也始终为空:

@RequestMapping(method = RequestMethod.POST, value = "/payments/confirm") public void receiveCallback(ServletInputStream inputStream) { try { inputStream.reset(); byte[] data = IOUtils.toByteArray(inputStream); File file = new File(System.getProperty("java.io.tmpdir") + "test" + System.currentTimeMillis() + ".txt"); FileOutputStream fos = new FileOutputStream(file); fos.write(data); fos.close(); } catch (Exception e) { logger.error("Error writing request", e); } } 

我也尝试过使用HttpServletRequest.getInputStream(),但结果相同。

使用InputStream不起作用(参见BalusC的回答)。 以下是如何使用HTTPServletRequest对象来编写标头和参数的示例:

 @RequestMapping(method = RequestMethod.POST, value = "/payments/confirm") public void receiveCallback(HttpServletRequest request) { try { StringBuilder sb = new StringBuilder(); sb.append("Headers:\n"); Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); Enumeration headers = request.getHeaders(headerName); while (headers.hasMoreElements()) { String headerValue = headers.nextElement(); sb.append(headerName).append(':').append(headerValue).append('\n'); } } sb.append("\nParameters:\n"); for(Entry entry: (Set) request.getParameterMap().entrySet(){ sb.append(entry.getKey()).append(':').append(entry.getValue()).append('\n'); } byte[] data = sb.toString().getBytes(); File file = new File(System.getProperty("java.io.tmpdir") + "test" + System.currentTimeMillis() + ".txt"); FileOutputStream fos = new FileOutputStream(file); fos.write(data); fos.close(); } catch (Exception e) { logger.error("Error writing request", e); } } 

我对Spring一无所知,但我至少可以告诉POST请求体只能读一次 。 它就是客户端发送到服务器的数据。 只要服务器需要多次,客户端就不会多次重新发送它。

我假设Spring已经读取了请求体,以便在进入Spring控制器方法之前解析所包含的查询字符串并获取请求参数。 这可以在Spring的封面下完成request.getParameter()和consorts。 在Servlet API中,一旦调用了该方法, request.getInputStream()request.getReader()将不会返回任何内容。 只是因为已经读取了请求体以返回参数。 这也在getParameter()的javadoc中提到过。

如果参数数据是在请求主体中发送的,例如HTTP POST请求,则直接通过getInputStream()getReader()读取主体可能会干扰此方法的执行。

最好的办法是创建一个filter ,在Spring完成其工作之前生成请求主体的副本,然后将filter放在Spring控制器的前面。 在HttpServletRequestWrapper帮助下,可以复制请求体,其中覆盖getInputStream()getReader()方法,首先将请求体读入ByteArrayInputStream和/或CharArrayReader以便您拥有本地副本然后返回它代替。 对HttpServletRequestWrapper的引用可以存储为请求属性,以便您可以在Spring控制器中将其作为请求属性获取,最后获取请求主体的副本。