Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

spring-boot

I want to define RestTemplate as an application bean using @Bean annotation in my configuration class in a spring boot application.

I am calling 4 rest services in different places in my application flow. Currently I am creating RestTemplate every time every request. Is there a way I can define that as application bean using @Bean and inject that using @Autowired?

Main reason for this question is I can able to define RestTemplate using @Bean but when I inject it with @Autowired I am loosing all defined interceptors (Interceptors are not getting called.)

Configuration Class

@Bean(name = "appRestClient")
public RestTemplate getRestClient() {

    RestTemplate  restClient = new RestTemplate(
        new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));

    List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
    interceptors.add(new RestServiceLoggingInterceptor());
    restClient.setInterceptors(interceptors);

    return restClient;
}

Service Class

public class MyServiceClass {

    @Autowired
    private RestTemplate appRestClient;

    public String callRestService() {
        // create uri, method response objects
        String restResp = appRestClient.getForObject(uri, method, response);
        // do something with the restResp
        // return String
    }
}

It seems my Interceptors are not getting called at all with this configuration. But RestTemplate is able to make a call to the REST service and get a response.

like image 213
springbootlearner Avatar asked Jul 22 '16 01:07

springbootlearner


2 Answers

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.

like image 140
Edd Avatar answered Sep 19 '22 06:09

Edd


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);
like image 22
Deva Avatar answered Sep 19 '22 06:09

Deva