Search code examples
restjerseyjax-rscxfjersey-2.0

How to inject ResourceInfo in javax.servlet.Filter


I am trying to register time metrics based on the service method but not able to inject ResourceInfo.

I want to write some generic logic to register the time based on the service.

Here is my code:

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.ws.rs.container.ResourceInfo;

@WebFilter("/*")
public class MetricsGeneraterFilter implements Filter {

    @Context
    private ResourceInfo resourceInfo;

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        long startTime = System.currentTimeMillis();
        chain.doFilter(request, response);
        long elapsedTime = System.currentTimeMillis() - startTime;
        System.out.println(resourceInfo.getResourceMethod().getName() + "--->" + elapsedTime);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

}

How to inject ResourceInfo in javax.servlet.Filter?


Solution

  • I've used ContainerRequestFilter and ContainerResponseFilter to solve for this problem.

    ContainerRequestFilter:

    @Provider
    public class RequestContextLoggingFilter implements ContainerRequestFilter{
    
        public static final String REQUEST_START_TIME = "REQUEST_START_TIME";
    
        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
    
            requestContext.setProperty(REQUEST_START_TIME, Instant.now());
        }
    }
    

    ContainerResponseFilter:

    @Provider
    @Priority(Priorities.USER)
    public class ResponseLogFilter implements ContainerResponseFilter{
    
    private Logger logger = LoggerFactory.getLogger(ResponseLogFilter.class);
    
    @Override
      public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
    
          try {
              Instant end = Instant.now();
              Instant start = (Instant) requestContext.getProperty(RequestContextLoggingFilter.REQUEST_START_TIME);
              logger.info("Done executing request with request_execution_time={} ms",
                    Duration.between(start, end).toMillis());
          }catch (Exception e){
              logger.warn("error logging response time", e);
          }
    
      }
    }
    

    You can also use Jersey's Monitoring and Diagnostics module: https://jersey.github.io/documentation/latest/monitoring_tracing.html.

    I haven't used it in production applications as it is in beta as of release >2.1