Spring:已经为此响应调用了getOutputStream()

时间:2014-01-10 08:37:12

标签: java spring outputstream illegalstateexception

我知道还有很多其他帖子处理同样的错误,但所有这些都是关于JSP / GSP页面的,或者出于任何其他原因在我的情况下不是很有用。我正在使用Spring MVC和Thymeleaf。以下功能用于下载文件。

@RequestMapping(value = "/test/download/*", method = RequestMethod.GET)
public String getFile(HttpServletResponse response)
{

    ServletOutputStream stream = null;
    try
    {
        stream = response.getOutputStream();

        MultipartFile f = test.getFile();

        InputStream is = f.getInputStream();
        IOUtils.copy(is, stream);
        response.flushBuffer();

        stream.flush();
        stream.close();

    } catch(Exception ex)
    {

    }

    return "test";

}

它确实有用,所以它不是太大的问题,但在控制台中,我总是收到以下错误:

2014-01-10T09:28:09.053+0100  SEVERE  Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception  [Request processing failed; nested exception is java.lang.IllegalStateException: getOutputStream() has already been called for this response] with root cause
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:638)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:214)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
at org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper.getWriter(SaveContextOnUpdateOrErrorResponseWrapper.java:125)
at org.thymeleaf.spring3.view.ThymeleafView.renderFragment(ThymeleafView.java:335)
at org.thymeleaf.spring3.view.ThymeleafView.render(ThymeleafView.java:190)
[...]

据我所知,getOutputStream()只被召唤一次。此外,整个函数被try-catch - 块包围。所以我想知道,这个错误来自哪里?

3 个答案:

答案 0 :(得分:4)

如果返回'test',则指示控制器在使用响应outputStream返回二进制文件后将其发送到某个视图。以下是您应该如何管理这个问题的想法:

Downloading a file from spring controllers

答案 1 :(得分:4)

我刚遇到这个问题。

问题是由我的控制器方法在退出时尝试返回类型字符串(视图名称)引起的。当该方法退出时,将启动第二个响应流。

将控制器方法返回类型更改为 void 解决了问题。

我希望如果其他人遇到这个问题,这会有所帮助。

答案 2 :(得分:2)

如果您想发送String,那么您可以更改

return "test";

return null;