简体   繁体   English

HttpsCookieFilter-IllegalStateException:此响应已调用getOutputStream()

[英]HttpsCookieFilter - IllegalStateException: getOutputStream() has already been called for this response

Following exception is thrown every once in a while and it shows up in localhost log file in tomcat log directory. 偶尔会抛出以下异常,并且该异常会显示在tomcat日志目录中的localhost日志文件中。 If anyone know how to get rid of it, all help would be appreciated. 如果有人知道如何摆脱它,所有帮助将不胜感激。 BTW the filter is working fine I just don't know why this exception is happening. 顺便说一句,过滤器工作正常,我只是不知道为什么会发生这种异常。

Stack trace: 堆栈跟踪:

java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:611)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:366)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:283)
at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:233)
at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:65)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176)
at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145)
at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:381)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:57)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)  

 //Here is the servlet I suspect is trowing the exception. 
 at package.HttpsCookieFilter.doFilter(HttpsCookieFilter.java:38)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:886)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:721)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2256)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:717)

The HttpsCookieFilter class: HttpsCookieFilter类:

public class HttpsCookieFilter implements Filter {
private static Logger log = Logger.getLogger(HttpsCookieFilter.class);

@Override
public void destroy() {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    final HttpServletRequest req = (HttpServletRequest) request;
    final HttpServletResponse res = (HttpServletResponse) response;
    final HttpSession session = req.getSession(false);

    if (session != null) {
       setCookie(req, res);
    }
    try{  

        chain.doFilter(request, response); // <- Exception thrown from here  

    }catch (IllegalStateException e){
        log.warn("HttpsCookieFilter redirect problem! ", e);
    }
}

@Override
public void init(FilterConfig arg0) throws ServletException {
}

 private void setCookie( HttpServletRequest request, HttpServletResponse response) {
    Cookie cookie = new Cookie("JSESSIONID", request.getSession(false).getId());
    cookie.setMaxAge(-1);
    cookie.setPath(getCookiePath(request));
    cookie.setSecure(false);
    response.addCookie(cookie);
}

private String getCookiePath(HttpServletRequest request) {
    String contextPath = request.getContextPath();
    return contextPath.length() > 0 ? contextPath : "/";
}
}  

web.xml web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd">

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

<filter>
    <filter-name>httpsCookieFilter</filter-name>
    <filter-class>com.iteezy.server.web.servlet.HttpsCookieFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>httpsCookieFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>filterChainProxy</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>filterChainProxy</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
...

The reason for integrating this filter comes from Spring security FAQs: 集成此过滤器的原因来自Spring安全性常见问题解答:

I'm using Tomcat (or some other servlet container) and have enabled HTTPS for my login page, switching back to HTTP afterwards. 我正在使用Tomcat(或其他一些servlet容器),并且已为登录页面启用HTTPS,然后再切换回HTTP。 It doesn't work - I just end up back at the login page after authenticating. 它不起作用-经过身份验证后,我只是回到登录页面。
This happens because sessions created under HTTPS, for which the session cookie is marked as “secure”, cannot subsequently be used under HTTP. 发生这种情况是因为在HTTPS下创建的会话(会话cookie标记为“安全”)无法随后在HTTP下使用。 The browser will not send the cookie back to the server and any session state will be lost (including the security context information). 浏览器不会将cookie发送回服务器,并且任何会话状态都将丢失(包括安全上下文信息)。 Starting a session in HTTP first should work as the session cookie won't be marked as secure. 首先使用HTTP启动会话应该可以正常工作,因为会话cookie不会被标记为安全。

Solution: 解:

As it turned out the culprit was: 事实证明,罪魁祸首是:

 @RequestMapping(value="/captcha.html", method = RequestMethod.GET)
 public ModelMap processCaptcha(HttpServletRequest request, HttpServletResponse response) throws Exception

Simple change of the return type of the method from ModalMap to void fixed the problem. 简单地将方法的返回类型从ModalMap更改为void即可解决此问题。 Thank you @BalusC 谢谢@BalusC

The filter has nothing to do with it. 过滤器与此无​​关。 It's just the point where the uncaught exception is been caught. 这只是捕获未捕获的异常的地方。

As the exception hints, you cannot call both getOutputStream() and getWriter() on the same response. 作为异常提示,您不能在同一响应上同时调用getOutputStream()getWriter() That's an illegal state. 那是非法状态。

As the stacktrace hints, you seem to be using Freemarker which is implicitly using the Writer to write the response body. 正如stacktrace所暗示的那样,您似乎正在使用Freemarker,它隐式使用Writer编写响应主体。 Whenever you delegate the response to Freemarker, you should thus ensure that you never call response.getOutputStream() anywhere in the code beforehand. 因此,无论何时将响应委派给Freemarker,都应确保永远不要事先在代码中的任何位置调用response.getOutputStream() Or, when calling it is mandatory (eg to write some binary content which is then to be provided as a download), then you should skip delegating the response to Freemarker. 或者,当调用它是强制性的(例如,编写一些二进制内容,然后将其作为下载内容提供)时,则应跳过将响应委派给Freemarker的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 IllegalStateException:已经为此响应调用了 getOutputStream() - IllegalStateException: getOutputStream() has already been called for this response IllegalStateException:检索图像时已对此响应调用getOutputStream() - IllegalStateException: getOutputStream() has already been called for this response on retrieving image java.lang.IllegalStateException:已经为此响应调用了 getOutputStream() - java.lang.IllegalStateException: getOutputStream() has already been called for this response java.lang.IllegalStateException:已为此响应调用了getOutputStream() - java.lang.IllegalStateException: getOutputStream() has already been called for this response 春季:已经为此响应调用了getOutputStream() - Spring: getOutputStream() has already been called for this response response.getOutputStream已被调用 - response.getOutputStream has already been called 已为此响应调用 getOutputStream() - getOutputStream() has already been called for this response 已为此响应调用HandlerInterceptor getOutputStream() - HandlerInterceptor getOutputStream() has already been called for this response JSP:已为此响应调用getOutputStream() - JSP : getOutputStream() has already been called for this response 此响应已调用“ getOutputStream()” - “getOutputStream()” has already been called for this response
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM