我想在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服务并获得响应。
从拦截器的名称来看,我猜您正在进行一些登录吗?您可能会错过日志记录级别配置。我创建了一个小应用程序,以使用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)
通过执行GET对http://localhost:8080/test我的请求,我应该期望得到String的hello!打印内容(该服务进行调用,http://localhost:8080然后返回hello!并发送给我)。带记录器的拦截器也会Intercepting...在控制台中打印出来。
如果您使用 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)
希望这可以帮助
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)
| 归档时间: |
|
| 查看次数: |
21385 次 |
| 最近记录: |