ContainerRequestFilter 和 ContainerResponseFilter 线程安全吗?

Posted

技术标签:

【中文标题】ContainerRequestFilter 和 ContainerResponseFilter 线程安全吗?【英文标题】:Are ContainerRequestFilter and ContainerResponseFilter thread safe? 【发布时间】:2017-03-23 14:25:37 【问题描述】:

我有下面的代码,它工作正常。我的问题是代码下面的天气是否是线程安全的。通过阅读 Servlet Filter 和 Container*Filter 概念,我感到很困惑。

如何使这个过滤器成为线程安全的?

 @Provider
public class ResourceLoggingFilter implements ContainerRequestFilter,   ContainerResponseFilter 

@Context
private ResourceInfo resourceInfo;

@Context
private HttpServletRequest  servletRequest;

@Inject
private java.util.logging.Logger logger;

public void filter(ContainerRequestContext requestContext,  ContainerResponseContext responseContext) throws IOException 
    String stTime = (String) requestContext.getProperty("StartTime"); 
    logger.log(Level.INFO,"<== Leaving Resource Path: "+ requestContext.getUriInfo().getPath());
    logger.log(Level.INFO,"<== Leaving Resource Method: "+  resourceInfo.getResourceMethod().getName());
    logger.log(Level.INFO,"<== Leaving Resource class: "+ resourceInfo.getResourceClass().getCanonicalName());
    logger.log(Level.INFO,"<== Leaving Session id: "+ servletRequest.getSession().getId());
    if (null == stTime || stTime.length() == 0) 
        logger.log(Level.INFO,"start-time not captured or cleared");
        stTime = "0";
    
    long startTime = Long.parseLong(stTime);
    long executionTime = System.nanoTime() - startTime;
    logger.log(Level.INFO,"Total execution time : "+executionTime+" nano seconds."  );



public void filter(ContainerRequestContext requestContext) throws IOException 
    requestContext.setProperty("StartTime", String.valueOf(System.nanoTime())); 
    logger.log(Level.INFO,"==> Entering Resource Path: "+ requestContext.getUriInfo().getPath());
    logger.log(Level.INFO,"==> Entering Resource Method: "+  resourceInfo.getResourceMethod().getName());
    logger.log(Level.INFO,"==> Entering Resource class: "+ resourceInfo.getResourceClass().getCanonicalName());
    logger.log(Level.INFO,"==> Entering Session id: "+ servletRequest.getSession().getId());




编辑private volatile String stTime;声明好不好,这样stTime可以是线程安全的??

【问题讨论】:

【参考方案1】:

它已经是线程安全的了。 ResourceInfoHttpServletRequest 都是代理(使用线程局部变量),而 java.util.Logger 上的方法是线程安全的。

另见:

Jersey 2: filters and @Context injections Request-scoped context field injections into RESTEasy singletons

【讨论】:

如果多个响应访问 String stTime = (String) requestContext.getProperty("StartTime"); ?? 感谢您的快速响应,我在想,filter() 响应不是线程安全的,stTime 被另一个响应/线程覆盖,而第一个线程在底部计算执行时间。 每个请求都有自己的 ContainerRequest(Response)Context。所以我没有关注你认为这可能会导致问题的地方

以上是关于ContainerRequestFilter 和 ContainerResponseFilter 线程安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用JAX-RS resteasy和ContainerRequestFilter / ContainerResponseFilter记录请求

如何将对象从 ContainerRequestFilter 传递到资源

如何在我的过滤器上过滤特定的URL以实现ContainerRequestFilter和ContainerResponseFilter?

Jersey ContainerRequestFilter 未触发

使用 ContainerRequestFilter 在 Jersey WebService 中自定义 @RolesAllowed 角色

泽西岛:ContainerRequestFilter 没有获得上下文 ServletRequest