JavaEE应用程序和过滤器中的写入程序和输出流
我最近遇到了以下异常 java.lang.IllegalStateException:无法获取Writer,因为OutputStream已在使用中 我理解例外的性质;也就是说,代码可以使用Writer或OutputStream,但不能在同一请求中同时使用这两个。在堆栈的下一层,代码应该如何处理已经存在的情况?或者是否有一种设计/拱形模式可以首先避免这个问题JavaEE应用程序和过滤器中的写入程序和输出流,java,servlets,jakarta-ee,servlet-filters,Java,Servlets,Jakarta Ee,Servlet Filters,我最近遇到了以下异常 java.lang.IllegalStateException:无法获取Writer,因为OutputStream已在使用中 我理解例外的性质;也就是说,代码可以使用Writer或OutputStream,但不能在同一请求中同时使用这两个。在堆栈的下一层,代码应该如何处理已经存在的情况?或者是否有一种设计/拱形模式可以首先避免这个问题 榜样;考虑一个第三方过滤器,它装饰一个请求的输出,并得到一个OuttoSt流。一个需要与编写器一起工作的过滤器或servlet如何“知道”一
榜样;考虑一个第三方过滤器,它装饰一个请求的输出,并得到一个OuttoSt流。一个需要与编写器一起工作的过滤器或servlet如何“知道”一个OutputStream已经打开,它应该关心吗?反之亦然。设计方法非常简单:
- 不要在JSP中使用Java代码(Scriptlet)。这会隐式触发
getWriter()
- 在转发到JSP时,不要向Servlet中的响应写入任何内容
换句话说,如果你坚持MVC理念,基本上就没有什么可担心的。设计方法非常简单:
- 不要在JSP中使用Java代码(Scriptlet)。这会隐式触发
getWriter()
- 在转发到JSP时,不要向Servlet中的响应写入任何内容
换句话说,如果你坚持MVC理念,基本上没有什么可担心的。我将尝试解决你的例子中提出的更具体的问题: 考虑一个第三方过滤器,它装饰请求的输出,并获得一个OutputStream。一个需要与编写器一起工作的过滤器或servlet如何“知道”一个OutputStream已经打开,它应该关心吗 Servlet API还不允许在填充响应时同时使用Writer和OutputStream,如API文档中所示: 可以调用此方法或getOutputStream()来编写主体,而不是同时调用两者 如果过滤器(第三方或其他方)想要写入响应,特别是在servlet生成响应之后,它应该假设
- servlet使用Writer或OutputStream来填充响应李>
- servlet将调用Writer或OutputStream对象上的
方法close()
如果过滤器首先填充响应(在进一步处理请求之前),则上述情况也适用。它应该在实际的HttpServletResponse对象上执行填充,向下游传递包装,然后将包装的内容写入实际对象。我将尝试解决您的示例中提出的更具体的问题: 考虑一个第三方过滤器,它装饰请求的输出,并获得一个OutputStream。一个需要与编写器一起工作的过滤器或servlet如何“知道”一个OutputStream已经打开,它应该关心吗 Servlet API还不允许在填充响应时同时使用Writer和OutputStream,如API文档中所示: 可以调用此方法或getOutputStream()来编写主体,而不是同时调用两者 如果过滤器(第三方或其他方)想要写入响应,特别是在servlet生成响应之后,它应该假设
- servlet使用Writer或OutputStream来填充响应李>
- servlet将调用Writer或OutputStream对象上的
方法close()
如果过滤器首先填充响应(在进一步处理请求之前),则上述情况也适用。它应该在实际的HttpServletResponse对象上执行填充,向下游传递包装器,然后将包装器的内容写入实际对象。另一种方法是设计
过滤器,以便根据web.xml
中的配置设置使用Writer或OutputStream。然后根据筛选请求的Servlet
配置过滤器
。另一种方法是设计过滤器
,以便根据web.xml
中的配置设置使用Writer或OutputStream。然后根据筛选请求的Servlet
配置过滤器。这是一个很好的建议,但它不处理过滤器需要修改应用程序生成的输出的情况。@Stephen:hm,我没有这样解释这个问题。但是,如果您的想法是正确的,那么只需在HttpServletResponseWrapper
实现的两个getter中添加两个布尔属性、一个if
检查和一个布尔切换即可。这是一个很好的建议,但是它不处理过滤器需要修改应用程序生成的输出的情况。@Stephen:hm,我没有这样解释这个问题。但是,如果您认为这是真的,那么只需在HttpServletResponseWrapper
实现的两个getter中添加两个布尔属性、一个if
检查和一个布尔切换即可。