我想在Spring启动应用程序的配置类中使用RestTemplate
注释将@Bean
定义为应用程序bean。
我在应用程序流程中的不同位置调用了4个休息服务。目前我每次请求都会创建RestTemplate
。有没有办法可以使用@Bean
将其定义为应用程序bean并使用@Autowired
注入?
这个问题的主要原因是我可以使用RestTemplate
定义@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;
}
服务类
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
}
}
看来我的Interceptors
根本没有被这个配置调用。但RestTemplate
能够调用REST服务并获得响应。
答案 0 :(得分:4)
判断拦截器的名称,我猜你在做一些登录?您可能错过了日志记录级别配置。我使用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;
}
}
版本创建了一个小应用程序来检查配置的工作天气。
在这个类中,我定义了application.properties
bean和带有日志记录的拦截器。
logging.level.com.example=DEBUG
为了记录工作,我还必须在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);
}
}
然后我创建了一个服务,我注入了这个@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();
}
}
。
GET
还有一个端点来测试它。
http://localhost:8080/test
通过向hello!
执行http://localhost:8080
请求,我应该会打印字符串hello!
(该服务会调用Intercepting...
并返回{{1}}并把它发回给我)。带记录器的拦截器也会在控制台中打印出{{1}}。
答案 1 :(得分:1)
@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;
}
现在您可以将bean自动装入服务类
@Autowired
@Qualifier("simpleRestTemplate")
private RestTemplate simpleRestTemplate;
希望这有帮助
答案 2 :(得分:1)
Spring boot 2。*。*版本的答案。
我正在使用 Spring boot 2.1.2RELEASE ,并且还在项目中存在邮件方法的类中添加了 RestTemplate 。
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.setConnectTimeout(Duration.ofMillis(300000))
.setReadTimeout(Duration.ofMillis(300000)).build();
}
并在我的服务或其他课程中使用
@Autowired
RestTemplate res;
和方法
HttpEntity<String> entity = new HttpEntity<>(str, headers);
return res.exchange(url, HttpMethod.POST, entity, Object.class);