问题描述
为了这就是我需要发生的事情:
In order this is what I need to happen:
请求在 blah.com/test
- ServletFilter A - 创建配置文件,然后调用
chain.doFilter
- ServletFilter B(因为 url 模式不匹配而被跳过)
- Servlet - 改变配置文件,
repsonse.setStatus
&response.addHeader("Location", target)
- ServletFilter A - 应该根据配置文件创建一个 cookie
实际发生的事情:
- ServletFilter A - 创建配置文件,然后调用
chain.doFilter
- ServletFilter B(因为 url 模式不匹配而被跳过)
- Servlet - 改变配置文件,
repsonse.setStatus
&response.addHeader("Location", target)
- 已提交重定向且 ServletFilter A 未完成任务
我认为这可能与您可以在 ServletFilter 配置中设置的调度程序值有关.
I think this may be related to the dispatcher values that you can set in the ServletFilter configs.
有什么想法吗?
推荐答案
我认为响应在 Step 4
到达 ServletFilter A
时正在提交.一旦响应被提交,即标头被写入客户端,您就不能进行需要添加标头的操作.添加cookie之类的操作.
I think the response is getting committed when it reaches ServletFilter A
at Step 4
. Once the response is committed, i.e, headers are written to the client, you cannot do operations which requires adding headers. The operations like adding cookies.
如果您希望在 Step 4
之前不提交响应,请尝试包装 HttpServletResponse
并返回您的自定义输出流,该流缓冲数据直到它到达 step 4
然后提交响应.
If you want the response not to be committed till Step 4
try wrapping HttpServletResponse
and returning your custom output stream which buffers the data till it reaches step 4
and then commits the response.
这是示例代码:
public class ResponseBufferFilter implements Filter
{
public void init(FilterConfig filterConfig) throws ServletException
{
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException
{
HttpServletResponse httpResponse = (HttpServletResponse)response;
BufferResponseWrapper wrapper = new BufferResponseWrapper(httpResponse);
filterChain.doFilter(request, resposneWrapper);
response.getOutputStream().write(wrapper .getWrapperBytes());
}
public void destroy()
{
}
private final class BufferResponseWrapper extends HttpServletResponseWrapper
{
MyServletOutputStream stream = new MyServletOutputStream();
public BufferResponseWrapper(HttpServletResponse httpServletResponse)
{
super(httpServletResponse);
}
public ServletOutputStream getOutputStream() throws IOException
{
return stream;
}
public PrintWriter getWriter() throws IOException
{
return new PrintWriter(stream);
}
public byte[] getWrapperBytes()
{
return stream.getBytes();
}
}
private final class MyServletOutputStream extends ServletOutputStream
{
private ByteArrayOutputStream out = new ByteArrayOutputStream();
public void write(int b) throws IOException
{
out.write(b);
}
public byte[] getBytes()
{
return out.toByteArray();
}
}
}
这篇关于响应正在提交并且 doFilter 链已损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!