如何在Servlet过滤器中添加自定义响应HTTP头,这取决于从应用返回的状态码



日志记录(MDC)当响应失败时,我需要设置一个自定义标头,如下所示:

public class MDCFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
MDC.put("trackingId", UUID.randomUUID().toString());
try {
chain.doFilter(request, response);
} catch (Throwable throwable) {
//suppress
}
if (((HttpServletResponse) response).getStatus() >= 300) {
((HttpServletResponse) response).setHeader("x-tracking-id", MDC.get("trackingId"));
//            ((HttpServletResponse) response).getHeader("x-tracking-id"); //this returns null
}
MDC.remove("trackingId");
}
}

但这不起作用,没有设置标题。如果我在chain.doFilter之前设置报头,它可以工作,但我需要尽可能晚地设置此过滤器,我需要知道响应状态是OK还是失败。

您需要在设置状态后立即设置报头,而不是在响应已经发送到客户端之后。这是一条不归路。可以使用HttpServletResponseWrapper来修饰setStatus()方法的行为。

例如,

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
MDC.put("trackingId", UUID.randomUUID().toString());
chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
@Override
public void setStatus(int status) {
super.setStatus(status);
if (status >= 300) {
setHeader("x-tracking-id", MDC.get("trackingId"));
}
}
});
}
finally {
MDC.remove("trackingId");
}
}

注意,我还修正了草率的异常处理。

相关内容

  • 没有找到相关文章

最新更新