How to Create or configure Rest Template using @Bean in Spring Boot

Judging form the name of the interceptor, I'm guessing you're doing some logging in it? You could of missed logging level configuration. I created a small application to check weather your configuration works, using 1.3.6.RELEASE version.

In this class I define the RestTemplate bean and the interceptor with logging.

package com.example;

// imports...

@SpringBootApplication
public class TestApplication {

    private static final Logger LOGGER = LoggerFactory.getLogger(TestApplication.class);

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

    @Bean(name = "appRestClient")
    public RestTemplate getRestClient() {
        RestTemplate restClient = new RestTemplate(
                new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));

        // Add one interceptor like in your example, except using anonymous class.
        restClient.setInterceptors(Collections.singletonList((request, body, execution) -> {

            LOGGER.debug("Intercepting...");
            return execution.execute(request, body);
        }));

        return restClient;
    }
}

For logging to work, I also have to set the correct debug level in application.properties.

logging.level.com.example=DEBUG

Then I create a service where I inject this RestTemplate.

@Service
public class SomeService {

    private final RestTemplate appRestClient;

    @Autowired
    public SomeService(@Qualifier("appRestClient") RestTemplate appRestClient) {
        this.appRestClient = appRestClient;
    }

    public String callRestService() {
        return appRestClient.getForObject("http://localhost:8080", String.class);
    }
}

And also an endpoint to test this out.

@RestController
public class SomeController {

    private final SomeService service;

    @Autowired
    public SomeController(SomeService service) {
        this.service = service;
    }

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String testEndpoint() {
        return "hello!";
    }

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public String test() {
        return service.callRestService();
    }
}

By performing a GET request to http://localhost:8080/test I should expect to get the String hello! getting printed (the service makes a call to http://localhost:8080 which returns hello! and sends this back to me). The interceptor with logger also prints out Intercepting... in the console.


Answer for Spring boot 2.*.* version.

I am using Spring boot 2.1.2.RELEASE and I also added RestTemplate in my project in a class where mail method exists.

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {

    return builder.setConnectTimeout(Duration.ofMillis(300000))
     .setReadTimeout(Duration.ofMillis(300000)).build();
}

and Used in my service or other classes like this

@Autowired
RestTemplate res;

and in methods

 HttpEntity<String> entity = new HttpEntity<>(str, headers);
            return res.exchange(url, HttpMethod.POST, entity, Object.class);

Edd's solution won't work if you're using Spring Boot 1.4.0 or later. You will have to use RestTemplateBuilder to get this working. Here is the example

@Bean(name="simpleRestTemplate")
@Primary
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){

    RestTemplate template = restTemplateBuilder.requestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()))
                                                .interceptors(logRestRequestInterceptor) //This is your custom interceptor bean
                                                .messageConverters(new MappingJackson2HttpMessageConverter())
                                                .build();
    return template;


}

Now you can autowire the bean into your service class

@Autowired
@Qualifier("simpleRestTemplate")
private RestTemplate simpleRestTemplate;

Hope this helps

Tags:

Spring Boot