在Spring MVC中写入文件请求

Eng*_*_DJ 4 java spring servlets 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Sea*_*oyd 7

使用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<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            Enumeration<String> 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<Entry>) 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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Bal*_*usC 5

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

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

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

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