Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.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
JavaEE应用程序和过滤器中的写入程序和输出流_Java_Servlets_Jakarta Ee_Servlet Filters - Fatal编程技术网

JavaEE应用程序和过滤器中的写入程序和输出流

JavaEE应用程序和过滤器中的写入程序和输出流,java,servlets,jakarta-ee,servlet-filters,Java,Servlets,Jakarta Ee,Servlet Filters,我最近遇到了以下异常 java.lang.IllegalStateException:无法获取Writer,因为OutputStream已在使用中 我理解例外的性质;也就是说,代码可以使用Writer或OutputStream,但不能在同一请求中同时使用这两个。在堆栈的下一层,代码应该如何处理已经存在的情况?或者是否有一种设计/拱形模式可以首先避免这个问题 榜样;考虑一个第三方过滤器,它装饰一个请求的输出,并得到一个OuttoSt流。一个需要与编写器一起工作的过滤器或servlet如何“知道”一

我最近遇到了以下异常

java.lang.IllegalStateException:无法获取Writer,因为OutputStream已在使用中

我理解例外的性质;也就是说,代码可以使用Writer或OutputStream,但不能在同一请求中同时使用这两个。在堆栈的下一层,代码应该如何处理已经存在的情况?或者是否有一种设计/拱形模式可以首先避免这个问题


榜样;考虑一个第三方过滤器,它装饰一个请求的输出,并得到一个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()
    方法
为了说明这一点,过滤器必须创建一个实例,将其向下传递给servlet进行填充,再次读回,然后填充实际的容器管理的HttpServletResponse对象


如果过滤器首先填充响应(在进一步处理请求之前),则上述情况也适用。它应该在实际的HttpServletResponse对象上执行填充,向下游传递包装,然后将包装的内容写入实际对象。

我将尝试解决您的示例中提出的更具体的问题:

考虑一个第三方过滤器,它装饰请求的输出,并获得一个OutputStream。一个需要与编写器一起工作的过滤器或servlet如何“知道”一个OutputStream已经打开,它应该关心吗

Servlet API还不允许在填充响应时同时使用Writer和OutputStream,如API文档中所示:

可以调用此方法或getOutputStream()来编写主体,而不是同时调用两者

如果过滤器(第三方或其他方)想要写入响应,特别是在servlet生成响应之后,它应该假设

  • servlet使用Writer或OutputStream来填充响应
  • servlet将调用Writer或OutputStream对象上的
    close()
    方法
为了说明这一点,过滤器必须创建一个实例,将其向下传递给servlet进行填充,再次读回,然后填充实际的容器管理的HttpServletResponse对象


如果过滤器首先填充响应(在进一步处理请求之前),则上述情况也适用。它应该在实际的HttpServletResponse对象上执行填充,向下游传递包装器,然后将包装器的内容写入实际对象。

另一种方法是设计
过滤器,以便根据
web.xml
中的配置设置使用Writer或OutputStream。然后根据筛选请求的
Servlet
配置
过滤器

另一种方法是设计
过滤器
,以便根据
web.xml
中的配置设置使用Writer或OutputStream。然后根据筛选请求的
Servlet
配置
过滤器。

这是一个很好的建议,但它不处理过滤器需要修改应用程序生成的输出的情况。@Stephen:hm,我没有这样解释这个问题。但是,如果您的想法是正确的,那么只需在
HttpServletResponseWrapper
实现的两个getter中添加两个布尔属性、一个
if
检查和一个布尔切换即可。这是一个很好的建议,但是它不处理过滤器需要修改应用程序生成的输出的情况。@Stephen:hm,我没有这样解释这个问题。但是,如果您认为这是真的,那么只需在
HttpServletResponseWrapper
实现的两个getter中添加两个布尔属性、一个
if
检查和一个布尔切换即可。