7

我正在尝试将一个添加到我的网络应用程序的日志中,如此requestId所示。

public class MDCFilter implements ContainerRequestFilter, ContainerResponseFilter
{
    private static final String CLIENT_ID = "client-id";

    @Context
    protected HttpServletRequest r;

    @Override
    public void filter(ContainerRequestContext req) throws IOException
    {
        Optional<String> clientId = Optional.fromNullable(r.getHeader("X-Forwarded-For"));
        MDC.put(CLIENT_ID, clientId.or(defaultClientId()));
    }

    @Override
    public void filter(ContainerRequestContext req, ContainerResponseContext resp) throws IOException
    {
        MDC.remove(CLIENT_ID);
    }

    private String defaultClientId()
    {
        return "Direct:" + r.getRemoteAddr();
    }
}

问题在于它在上述过滤器中设置和删除 requestIdMDC我还使用WriterInterceptor. 问题是,由于拦截器在过滤器之后运行,所以当我WriterInterceptor执行时,没有 requestId 在MDC.

MDC.clear()我的问题是,是否可以在结束时打电话WriterInterceptor(感觉有点骇人听闻),还是有更好的方法来实现这一点?

4

1 回答 1

0

我有同样的问题。这就是它目前在我正在开发的代码中的工作方式

@Order(Ordered.HIGHEST_PRECEDENCE)
public final class RequestFilter implements Filter {
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
      //stuff
      chain.doFilter(request, response);
    } finally {
      // this clears a specific entry from the MDC but not the entire MDC
      RequestContext.clear();
    }
  }
}

可以在这里的 finally 块中清除整个 MDC ......但我不知道 Spring 何时记录异常。我会不会太早清除?我的新计划是在我开始请求时清除 MDC。

我不确定这是否是一个完整的答案,但是在我的最高优先级过滤器中清除 MDC 应该可以。

于 2019-06-27T15:51:36.677 回答