159

What is the right way to add HttpRequest interceptors in spring boot application? What I want to do is log requests and responses for every http request.

Spring boot documentation does not cover this topic at all. (http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/)

I found some web samples on how to do the same with older versions of spring, but those work with applicationcontext.xml. Please help.

xenteros
  • 15,586
  • 12
  • 56
  • 91
hrishikeshp19
  • 8,838
  • 26
  • 78
  • 141
  • Hi @riship89... I have implemented `HandlerInterceptor` successfully. It is working fine. Only the problem is, some `internal HandlerInterceptor` throws an exception before it is handled by the `custom HandlerInterceptor`. The `afterCompletion()` method which is overridden is called after the error is thrown by the internal implementation of HandlerInterceptor. Do you have solution for this? – Chetan Oswal May 24 '20 at 13:55
  • For future readers, here is the awesome video tutorial that explains how Spring interceptor works https://www.youtube.com/watch?v=DuMf8Nwb-9w – Nilanchala Aug 06 '23 at 23:04

10 Answers10

195

Since you're using Spring Boot, I assume you'd prefer to rely on Spring's auto configuration where possible. To add additional custom configuration like your interceptors, just provide a configuration or bean of WebMvcConfigurerAdapter.

Here's an example of a config class:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

  @Autowired 
  HandlerInterceptor yourInjectedInterceptor;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(...)
    ...
    registry.addInterceptor(getYourInterceptor()); 
    registry.addInterceptor(yourInjectedInterceptor);
    // next two should be avoid -- tightly coupled and not very testable
    registry.addInterceptor(new YourInterceptor());
    registry.addInterceptor(new HandlerInterceptor() {
        ...
    });
  }
}

NOTE do not annotate this with @EnableWebMvc, if you want to keep Spring Boots auto configuration for mvc.

Gaʀʀʏ
  • 4,372
  • 3
  • 39
  • 59
ikumen
  • 11,275
  • 4
  • 41
  • 41
  • Nice! Looks good! Any example of what goes inside registry.addInterceptor(...)? Just curious to know a sample of "..." – hrishikeshp19 Jun 26 '15 at 22:56
  • nothing special, just add your interceptor to the registry – ikumen Jun 26 '15 at 23:08
  • coming back to this, can you post example implementation of "yourInjectedInceptor"? – hrishikeshp19 Jan 18 '16 at 20:08
  • 12
    use @Component annotation on yourInjectedInceptor – Paolo Biavati Feb 22 '16 at 22:40
  • 1
    @riship89 Checkout this for an example: http://www.mkyong.com/spring-mvc/spring-mvc-handler-interceptors-example/ – Vlad Manuel Mureșan Mar 28 '16 at 12:10
  • I'm hoping for help here... when I use the "myInjectedInterceptor" approach, any property placeholders I have in my interceptor, which are annotated with "@Value" are only getting my configured value if I do NOT declare a default. @Value("my.property:defaultValue") <-- uses default instead of configured value @Value("my.property") <-- uses configured value Any idea why? – Nephthys76 Jan 25 '17 at 21:05
  • Using this way, I get `getReader() has already been called for this request` error. Is that because the request getting deserialized twice? How to overcome that issue – vigamage Aug 12 '17 at 16:05
  • Beware that this is not silver bullet for all HTTP requests (for example the spring-data-rest ones). If you want ALL do MappedInterceptor and map it to /** – Jan Zyka May 30 '18 at 10:22
  • 8
    I get error `The type WebMvcConfigurerAdapter is deprecated`. I am using Spring Web MVC 5.0.6 – John Henckel Jun 15 '18 at 21:22
  • 15
    In Spring 5, just implement WebMvcConfigurer instead of extending WebMvcConfigurerAdapter. Since Java 8 interfaces allow default implementations, it is no longer required to use the adapter (which is why it's deprecated). – edgraaff Oct 23 '18 at 07:22
  • I have one question, I have implemented an Interceptor for my springboot app, and it is not executed, when calling addInterceptor I have added `addPathsPatern("/**")` for all paths. My question is does this Interceptor intercept all methods? Thank you – Bionix1441 Jun 18 '20 at 11:06
  • This does not intercept requests to inbuilt endpoints such as `/actuator/health` – Tejesh Raut Jul 24 '20 at 11:08
  • 1
    thanks for the call out to not add @EnableWebMvc. it was screwing up my spring-boot app – arvin_v_s Aug 03 '20 at 11:57
  • 1
    can you elaborate why @EnableWebMvc causes problem – Aditya Nov 25 '21 at 17:50
143

WebMvcConfigurerAdapter will be deprecated with Spring 5. From its Javadoc:

@deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made possible by a Java 8 baseline) and can be implemented directly without the need for this adapter

As stated above, what you should do is implementing WebMvcConfigurer and overriding addInterceptors method.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyCustomInterceptor());
    }
}
sedooe
  • 3,100
  • 2
  • 22
  • 27
  • 29
    Your answer is incomplete because it's missing the implementation of `MyCustomInterceptor` – Peter Chaula Jan 06 '19 at 20:51
  • 3
    @AndriiDzhyrma, you have to write code that is comprehensible to a total beginner. Have a look at this complete answer and you'll get my point. https://stackoverflow.com/a/42113069/4187541 – Peter Chaula May 20 '21 at 15:33
50

To add interceptor to a spring boot application, do the following

  1. Create an interceptor class

    public class MyCustomInterceptor implements HandlerInterceptor{
    
        //unimplemented methods comes here. Define the following method so that it     
        //will handle the request before it is passed to the controller.
    
        @Override
        public boolean preHandle(HttpServletRequest request,HttpServletResponse  response){
        //your custom logic here.
            return true;
        }
    }
    
  2. Define a configuration class

    @Configuration
    public class MyConfig extends WebMvcConfigurerAdapter{
        @Override
        public void addInterceptors(InterceptorRegistry registry){
            registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("/**");
        }
    }
    
  3. Thats it. Now all your requests will pass through the logic defined under preHandle() method of MyCustomInterceptor.

Rudi Kershaw
  • 12,332
  • 7
  • 52
  • 77
sunitha
  • 1,468
  • 14
  • 18
  • 1
    I have followed this way to intercept the signup requests come to my application in order to do some common validations. But the problem is i get the `getReader() has already been called for this request` error. Is there any simpler way to get over this without using a copy of the actual request ? – vigamage Aug 12 '17 at 15:47
  • When the pre-handler is called, the request body is not available, but only parameters, To do validation on the request body, the prefered way will be to use Aspect J and create `Advice` – Hima Aug 18 '18 at 15:15
43

Since all responses to this make use of the now long-deprecated abstract WebMvcConfigurer Adapter instead of the WebMvcInterface (as already noted by @sebdooe), here is a working minimal example for a SpringBoot (2.1.4) application with an Interceptor:

Minimal.java:

@SpringBootApplication
public class Minimal
{
    public static void main(String[] args)
    {
        SpringApplication.run(Minimal.class, args);
    }
}

MinimalController.java:

@RestController
@RequestMapping("/")
public class Controller
{
    @GetMapping("/")
    @ResponseBody
    public ResponseEntity<String> getMinimal()
    {
        System.out.println("MINIMAL: GETMINIMAL()");

        return new ResponseEntity<String>("returnstring", HttpStatus.OK);
    }
}

Config.java:

@Configuration
public class Config implements WebMvcConfigurer
{
    //@Autowired
    //MinimalInterceptor minimalInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
        registry.addInterceptor(new MinimalInterceptor());
    }
}

MinimalInterceptor.java:

public class MinimalInterceptor extends HandlerInterceptorAdapter
{
    @Override
    public boolean preHandle(HttpServletRequest requestServlet, HttpServletResponse responseServlet, Object handler) throws Exception
    {
        System.out.println("MINIMAL: INTERCEPTOR PREHANDLE CALLED");

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
    {
        System.out.println("MINIMAL: INTERCEPTOR POSTHANDLE CALLED");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception
    {
        System.out.println("MINIMAL: INTERCEPTOR AFTERCOMPLETION CALLED");
    }
}

works as advertised

The output will give you something like:

> Task :Minimal.main()

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.4.RELEASE)

2019-04-29 11:53:47.560  INFO 4593 --- [           main] io.minimal.Minimal                       : Starting Minimal on y with PID 4593 (/x/y/z/spring-minimal/build/classes/java/main started by x in /x/y/z/spring-minimal)
2019-04-29 11:53:47.563  INFO 4593 --- [           main] io.minimal.Minimal                       : No active profile set, falling back to default profiles: default
2019-04-29 11:53:48.745  INFO 4593 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-04-29 11:53:48.780  INFO 4593 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-04-29 11:53:48.781  INFO 4593 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.17]
2019-04-29 11:53:48.892  INFO 4593 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-04-29 11:53:48.893  INFO 4593 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1269 ms
2019-04-29 11:53:49.130  INFO 4593 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-04-29 11:53:49.375  INFO 4593 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-04-29 11:53:49.380  INFO 4593 --- [           main] io.minimal.Minimal                       : Started Minimal in 2.525 seconds (JVM running for 2.9)
2019-04-29 11:54:01.267  INFO 4593 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-04-29 11:54:01.267  INFO 4593 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-04-29 11:54:01.286  INFO 4593 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 19 ms
MINIMAL: INTERCEPTOR PREHANDLE CALLED
MINIMAL: GETMINIMAL()
MINIMAL: INTERCEPTOR POSTHANDLE CALLED
MINIMAL: INTERCEPTOR AFTERCOMPLETION CALLED
Xenonite
  • 1,823
  • 4
  • 26
  • 39
16

I had the same issue of WebMvcConfigurerAdapter being deprecated. When I searched for examples, I hardly found any implemented code. Here is a piece of working code.

create a class that extends HandlerInterceptorAdapter

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import me.rajnarayanan.datatest.DataTestApplication;
@Component
public class EmployeeInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = LoggerFactory.getLogger(DataTestApplication.class);
    @Override
    public boolean preHandle(HttpServletRequest request, 
            HttpServletResponse response, Object handler) throws Exception {

            String x = request.getMethod();
            logger.info(x + "intercepted");
        return true;
    }

}

then Implement WebMvcConfigurer interface

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import me.rajnarayanan.datatest.interceptor.EmployeeInterceptor;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    EmployeeInterceptor employeeInterceptor ;

    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(employeeInterceptor).addPathPatterns("/employee");
    }
}
user2532195
  • 171
  • 1
  • 3
  • 4
    how can u only override one method on an interface without compilation issues? – xetra11 Nov 29 '17 at 16:17
  • 1
    @xetra11 I am also trying to see if we can only implement one method instead of all other methods not used in this case. Is it possible? Did you figured that out? – user09 May 29 '18 at 17:12
  • 4
    @arjun The others are implemented as [default methods](https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html) thanks to Java 8. This reasoning is, conveniently, [documented](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.html) in the deprecated class. – Bob May 30 '18 at 06:17
16

I found a good tutorial on this site on how to add request interceptors to specific controllers using annotations:

  1. Define the annotation
  2. Define the interceptor
  3. Add the interceptor to the path
  4. Use the annotation on the specific controller

https://programmer.group/how-do-spring-boot-2.x-add-interceptors.html

I know this question was how to add interceptors to all requests and that's answered already. I was searching the solution to add request interceptors to specific controllers using annotations but couldn't find a solution in stackoverflow. Decided add this content to this question instead of asking a new question.

Define the annotation NeedLogin.class

package com.example.helloSpringBoot.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedLogin {
}

Then define the inceptor class

package com.example.helloSpringBoot.config;

import com.example.helloSpringBoot.annotation.NeedLogin;
import com.example.helloSpringBoot.util.WxUserInfoContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Logon interceptor
 *
 * @Author: Java Fragment
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    //This method is executed before accessing the interface. We only need to write the business logic to verify the login status here to verify the login status before the user calls the specified interface.
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (handler instanceof HandlerMethod) {
            NeedLogin needLogin = ((HandlerMethod) handler).getMethodAnnotation(NeedLogin.class);
            if (null == needLogin) {
                needLogin = ((HandlerMethod) handler).getMethod().getDeclaringClass()
                        .getAnnotation(NeedLogin.class);
            }
            // Check login if you have login validation annotations
            if (null != needLogin) {
                WxUserInfoContext curUserContext = (WxUserInfoContext) request.getSession()
                        .getAttribute("curUserContext");
                //If session No, not logged in.
                if (null == curUserContext) {
                    response.setCharacterEncoding("UTF-8");
                    response.getWriter().write("Not logged in!");
                    return false;
                }
            }

        }
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

Then add the inceptor into the WebConfig

package com.example.helloSpringBoot.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * WebConfig
 *
 * @Author: Java Fragment
 *
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // Custom interceptor, add intercept path and exclude intercept path
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
    }
}

Finally you are free to use the new interceptor using the new annotation @NeedLogin

package com.example.helloSpringBoot.controller;

import com.example.helloSpringBoot.annotation.NeedLogin;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    /**
     * Testing does not require login
     *
     *
     */
    @RequestMapping("/testNoLogin")
    public String testNoLogin (){
        return "The call is successful, this interface does not need login validation!-Java Broken read!";
    }

    /**
     * Testing requires login
     *
     *
     */
    @NeedLogin
    @RequestMapping("/testNeedLogin")
    public String testNeedLogin (){
        return "testNeedLogin!";
    }
}
Ng Zhong Qin
  • 1,211
  • 2
  • 15
  • 28
7

You might also consider using the open source SpringSandwich library which lets you directly annotate in your Spring Boot controllers which interceptors to apply, much in the same way you annotate your url routes.

That way, no typo-prone Strings floating around -- SpringSandwich's method and class annotations easily survive refactoring and make it clear what's being applied where. (Disclosure: I'm the author).

http://springsandwich.com/

Magnus
  • 10,736
  • 5
  • 44
  • 57
  • That looks awesome! I've created an issue asking for SpringSandwich to be available in maven central to make it easier to use for projects that are building under CI or which are deploying via Heroku. – Brendon Dugan Feb 14 '17 at 22:16
  • Great. Is it available in maven central repository? Re - blogging http://springsandwich.com/ in my website with the reference of your git repository and reference – Arpan Das Apr 24 '17 at 18:12
  • 1
    SpringSandwich is now in Maven Central – Magnus Apr 26 '17 at 13:50
  • 1
    Looks like this library has been abandonned since 2017 – Josh Lemer Jun 03 '21 at 15:25
2

For tracking all the request response in the spring-boot (java) application you can create a filter class like this -

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
public class RequestResponseTracker extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);

        filterChain.doFilter(requestWrapper, responseWrapper);

        System.out.println("Request URI: " + request.getRequestURI());
        System.out.println("Request Headers: " + Collections.list(request.getHeaderNames()).stream()
                .map(headerName -> headerName + " -> " + request.getHeader(headerName)).collect(Collectors.toList()));
        System.out.println("Request Method: " + request.getMethod());
        System.out.println("Request Body: " + getStringValue(requestWrapper.getContentAsByteArray(),
                responseWrapper.getCharacterEncoding()));

        System.out.println("Response Code: " + response.getStatus());
        System.out.println("Response Body: " + getStringValue(responseWrapper.getContentAsByteArray(),
                responseWrapper.getCharacterEncoding()));
        System.out.println("Response Headers: " + response.getHeaderNames().stream()
                .map(headerName -> headerName + " -> " + response.getHeader(headerName)).collect(Collectors.toList()));

        responseWrapper.copyBodyToResponse();   // Don't forget to add this at the end
    }


    private String getStringValue(byte[] contentAsByteArray, String characterEncoding) {
        try {
            return new String(contentAsByteArray, 0, contentAsByteArray.length,
                    Objects.nonNull(characterEncoding) ? characterEncoding : StandardCharsets.UTF_8.name());
        }
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
}
Rahul Tiwari
  • 269
  • 2
  • 6
1

I will recommend the following ways to dynamically inject custom interceptors.
You don't need to add interceptors one by one.

CustomInterceptor:

public interface CustomInterceptor extends HandlerInterceptor {

default String[] excludePathPatterns() {
    return new String[]{
        "/*/*.html",
        "/*/*.css",
        "/*/*.js",
        "/*/*.png",
        "/*/*.xml",
        "/*/*.json",
        "/*/*.yaml",
        "/*/*.yml",
        "/swagger*/**"
      };
    }


    default String[] pathPatterns() {
        return new String[]{"/**"};
    }
}

WebMvcConfig:

@Slf4j
@Configuration
@RequiredArgsConstructor
@SuppressWarnings("NullableProblems")
@ConditionalOnProperty(name = AutoConfigConstants.ENABLE_MVC, havingValue = "true")
public class DefaultMvcAutoConfiguration implements WebMvcConfigurer {

    static {
        log.info(AutoConfigConstants.LOADING_MVC_AUTO_CONFIGURE);
    }

    private final List<CustomInterceptor> customInterceptors;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        WebMvcConfigurer.super.addInterceptors(registry);
        if (CollectionUtils.isNotEmpty(customInterceptors)) {
            customInterceptors.forEach(customInterceptor ->
                registry.addInterceptor(customInterceptor)
                    .addPathPatterns(customInterceptor.pathPatterns())      
         .excludePathPatterns(customInterceptor.excludePathPatterns()));
        }
    }
}
CloudSen
  • 103
  • 2
  • 12
-1

Below is an implementation I use to intercept each HTTP request before it goes out and the response which comes back. With this implementation, I also have a single point where I can pass any header value with the request.

public class HttpInterceptor implements ClientHttpRequestInterceptor {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public ClientHttpResponse intercept(
        HttpRequest request, byte[] body,
        ClientHttpRequestExecution execution
) throws IOException {
    HttpHeaders headers = request.getHeaders();
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
    headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
    traceRequest(request, body);
    ClientHttpResponse response = execution.execute(request, body);
    traceResponse(response);
    return response;
}

private void traceRequest(HttpRequest request, byte[] body) throws IOException {
    logger.info("===========================Request begin======================================");
    logger.info("URI         : {}", request.getURI());
    logger.info("Method      : {}", request.getMethod());
    logger.info("Headers     : {}", request.getHeaders() );
    logger.info("Request body: {}", new String(body, StandardCharsets.UTF_8));
    logger.info("==========================Request end=========================================");
}

private void traceResponse(ClientHttpResponse response) throws IOException {
    logger.info("============================Response begin====================================");
    logger.info("Status code  : {}", response.getStatusCode());
    logger.info("Status text  : {}", response.getStatusText());
    logger.info("Headers      : {}", response.getHeaders());
    logger.info("=======================Response end===========================================");
}}

Below is the Rest Template Bean

@Bean
public RestTemplate restTemplate(HttpClient httpClient)
{
    HttpComponentsClientHttpRequestFactory requestFactory =
            new HttpComponentsClientHttpRequestFactory();
    requestFactory.setHttpClient(httpClient);
    RestTemplate restTemplate=  new RestTemplate(requestFactory);
    List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
    if (CollectionUtils.isEmpty(interceptors))
    {
        interceptors = new ArrayList<>();
    }
    interceptors.add(new HttpInterceptor());
    restTemplate.setInterceptors(interceptors);

    return restTemplate;
}
Sylvester
  • 179
  • 1
  • 14
  • 4
    OK but what you've actually done here is an interceptor FOR RestTemplate (i.e. when YOU make HTTP calls)... not an interceptor for Spring REST Controllers (i.e. when HTTP calls are made against your Spring app/REST-webservices). – maxxyme Sep 03 '20 at 08:13
  • 1
    The question is about HTTP calls to your controller not HTTP calls from your application which RestTemplate handles. Thanks to @maxxyme comment. – Tunde Michael Dec 05 '21 at 21:30