Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在SpringMVC中向文件写入请求_Java_Spring_Servlets_Spring Mvc - Fatal编程技术网

Java 在SpringMVC中向文件写入请求

Java 在SpringMVC中向文件写入请求,java,spring,servlets,spring-mvc,Java,Spring,Servlets,Spring Mvc,我希望能够将整个请求写入SpringMVC控制器中的文件 我尝试了以下方法,但即使我使用大量参数发出POST请求,文件始终为空: @RequestMapping(method = RequestMethod.POST, value = "/payments/confirm") public void receiveCallback(ServletInputStream inputStream) { try { inputStream.reset();

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

我尝试了以下方法,但即使我使用大量参数发出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);
    }
}
@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);
    }
}

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

我对Spring一无所知,但我至少可以告诉你,请求后的正文只能读取一次。这就是客户机发送给服务器的数据。只要服务器多次需要,客户端就不会多次重新发送

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

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


最好的办法是创建一个在Spring执行其工作之前复制请求主体的过滤器,然后将过滤器放在Spring控制器前面。可以通过重写
getInputStream()
getReader()
方法来创建请求正文的副本,以首先将请求正文读入
ByteArrayInputStream
和/或
CharArrayReader
中,从而获得本地副本,然后返回它。对HttpServletRequestWrapper的引用可以存储为请求属性,这样您就可以在Spring控制器中获取它作为请求属性,并最终获取请求正文的副本。

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

    @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);
    }
}
@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);
    }
}
@RequestMapping(method=RequestMethod.POST,value=“/payments/confirm”)
public void receiveCallback(HttpServletRequest){
试一试{
StringBuilder sb=新的StringBuilder();
sb.追加(“标题:\n”);
枚举headerNames=request.getHeaderNames();
while(headerNames.hasMoreElements()){
字符串headerName=headerName.nextElement();
枚举头=request.getHeaders(headerName);
while(headers.hasMoreElements()){
字符串headerValue=headers.nextElement();
sb.append(headerName).append(':').append(headerValue).append('\n');
}
}
sb.追加(“\n参数:\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=新文件(System.getProperty(“java.io.tmpdir”)+“test”
+System.currentTimeMillis()+“.txt”);
FileOutputStream fos=新的FileOutputStream(文件);
写入(数据);
fos.close();
}捕获(例外e){
记录器错误(“错误写入请求”,e);
}
}

智能替代方案。但是,根据定义,请求头不是请求正文的一部分。正常的
应用程序/x-www-form-urlencoded
请求正文由URL编码的请求参数名称=值对
&
-以查询字符串的形式连接而成(与您在
之后在GET request URI中看到的完全相同)。此外,参数映射的值是
字符串[]
,而不是您似乎期望的
字符串
。最后要注意字符编码的差异。平台的默认值已在
getBytes()中使用
虽然参数可以用完全不同的编码进行解析。@BalusC true,但我并没有试图重新创建原始请求,只是为了生成一些调试信息。由于您列出的原因,重新创建原始请求是不可能的。啊,是的。如果业务需要,这无论如何都是一个非常好且简单的选择足够灵活:)+1的基本想法,我完全没有想到。