简体   繁体   中英

Java interceptor to process the REST API response code

I have a requirement to intercept the REST API responses for out application and do something with them. One very obvious approach to achieve this is to define an annotation and interceptor at method level (so that it can be applied to the REST API methods). However, I could not find a way to extract/intercept the response code for API responses. I am very new to Java EE world, so might be missing something here, but didn't find anything on internet search either. Our application is based on standard JavaEE with CXF.

I have seen some examples with code similar to the following, but not sure how I can get the API response from that. Any help would be appreciated.

@AroundInvoke
public Object around(InvocationContext context) throws Exception {......

Suppose you are using the standard JEE solution, from the doc

@AroundInvoke
public Object logInvocation(InvocationContext ctx) throws Exception {
   String class = ctx.getMethod().getDeclaringClass().getName();
   String method = ctx.getMethod().getName();
   Logger.global.entering(class, method, ctx.getParameters());
   try {
      Object result = ctx.proceed();
      Logger.global.exiting(class, method, result);
      return result;
   }
   catch (Exception e) {
      Logger.global.throwing(class, method, e);
      throw e;
   }

}

The Object result = ctx.proceed(); is the result for you.

JAX-RS server filters

Use a ContainerResponseFilter from the JAX-RS API 2.0 to intercept responses or server side:

@Provider
public class CustomResponseFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, 
                       ContainerResponseContext responseContext) throws IOException {

        // Intercept the HTTP response and get the status code
        int status = responseContext.getStatus()
    }
}

The JAX-RS 2.0 API also provide the ContainerRequestFilter to intercept requests:

@Provider
public class CustomRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        // Intercept the HTTP request
    }
}

To bind the filters to resource classes and/or methods, use name binding annotations .

Registering server filters in Apache CXF

According to the Apache CXF documentation , the filters must be registered in the cxf.xml configuration file. This file must be in the classpath of your application.

Here's an example extracted from the documentation of what your CXF configuration file can be like when registering a filter:

<beans>
    <jaxrs:server id="customerService" address="/">

        <jaxrs:serviceBeans>
          <bean class="org.CustomerService" />
        </jaxrs:serviceBeans>

        <jaxrs:providers>
          <ref bean="authorizationFilter" />
        </jaxrs:providers>

        <bean id="authorizationFilter" class="com.bar.providers.AuthorizationFilter">
            <!-- authorization bean properties -->
        </bean>

    </jaxrs:server>
</beans>

For more details, check the CXF documentation about configuration .

Although interceptors are a great way to do cross-cutting concerns for your application services , you are talking about a web application here. You are not looking at intercepting service request, you are looking at intercepting http requests.

Web applications use the servlet spec, and for such generic stuff you'd use @Webfilter s. These webfilters can get the entire request and response, including the status code, as they work on the transport level, and not on the application level.

Be mindful that the servlet spec is picky: you cannot easily read requests and responses without duplicating them, and it's a bit messy code. Google a bit for it (log http request, log http response) and you should find plenty of code to create a filter which can do that.

Hi you didn't mention what technology stack. If you needed something for client side you could use Spring and Spring's ClientHttpRequestInterceptor.

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    ClientHttpResponse response = execution.execute(request, body);
    /**
     * response.getStatusCode();
     */
    return response;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM