如何在Spring Boot中使用@Bean创建或配置Rest模板

spr*_*ner 3 spring-boot

我想在Spring Boot应用程序的配置类中RestTemplate使用@Bean注释定义为应用程序bean 。

我在应用程序流程中的不同位置调用了4个REST服务。目前,我RestTemplate每次创建每个请求。有没有一种方法可以将其定义为application bean using @Bean并使用using 注入@Autowired

这个问题的主要原因是我可以定义RestTemplateusing,@Bean但是当我注入它时,我将@Autowired失去所有定义的拦截器(拦截器不会被调用。)

配置类别

@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;
}
Run Code Online (Sandbox Code Playgroud)

服务等级

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
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎我Interceptors完全没有被这种配置调用。但是RestTemplate能够调用REST服务并获得响应。

Edd*_*Edd 6

从拦截器的名称来看,我猜您正在进行一些登录吗?您可能会错过日志记录级别配置。我创建了一个小应用程序,以使用1.3.6.RELEASE版本检查您的配置工作情况。

在此类中,我RestTemplate使用日志记录定义了bean和拦截器。

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

为了使日志正常工作,我还必须在中设置正确的调试级别application.properties

logging.level.com.example=DEBUG
Run Code Online (Sandbox Code Playgroud)

然后,我在其中注入服务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);
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个端点来测试这一点。

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

通过执行GEThttp://localhost:8080/test我的请求,我应该期望得到String的hello!打印内容(该服务进行调用,http://localhost:8080然后返回hello!并发送给我)。带记录器的拦截器也会Intercepting...在控制台中打印出来。


Abh*_*bhi 5

如果您使用 Spring Boot 1.4.0 或更高版本,Edd 的解决方案将不起作用。您必须使用 RestTemplateBuilder 才能使其正常工作。这是例子

@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;


}
Run Code Online (Sandbox Code Playgroud)

现在您可以将 bean 自动装配到您的服务类中

@Autowired
@Qualifier("simpleRestTemplate")
private RestTemplate simpleRestTemplate;
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


Dev*_*eva 5

Spring boot 2.*.* 版本的答案。

我正在使用Spring boot 2.1.2.RELEASE,并且还在我的项目中存在邮件方法的类中添加了RestTemplate

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {

    return builder.setConnectTimeout(Duration.ofMillis(300000))
     .setReadTimeout(Duration.ofMillis(300000)).build();
}
Run Code Online (Sandbox Code Playgroud)

并在我的服务或其他类似的课程中使用

@Autowired
RestTemplate res;
Run Code Online (Sandbox Code Playgroud)

在方法中

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