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

新手上路,请多包涵

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

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

这个问题的主要原因是我可以定义 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 服务并获得响应。

原文由 springbootlearner 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 771
2 个回答

从拦截器的名称来看,我猜你正在登录它?您可能会错过 日志级别配置。我使用 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;
    }
}

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

 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...

原文由 Edd 发布,翻译遵循 CC BY-SA 3.0 许可协议

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();
}

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

@Autowired
RestTemplate res;

在方法中

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

原文由 Deva 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进