Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring启动程序-RestTemplate_Java_Spring Boot_Resttemplate - Fatal编程技术网

Java Spring启动程序-RestTemplate

Java Spring启动程序-RestTemplate,java,spring-boot,resttemplate,Java,Spring Boot,Resttemplate,我目前正在尝试编写一个SpringBootStarter,它将使用API网关自动验证我们的微服务,并将访问令牌包含在所有传出请求(指向网关)的头中我正在创建一个RESTTemplatebean,并将我们的自定义拦截器提供给它,但我的问题是,通过这样做,我阻止了其他团队(将使用此初学者)使用他们自己的RestTemplate配置,因为他们必须定义同一个bean,从而导致存在多个bean @Bean public RestTemplate restTemplate(){ RestTemplate

我目前正在尝试编写一个SpringBootStarter,它将使用API网关自动验证我们的微服务,并将访问令牌包含在所有传出请求(指向网关)的头中
我正在创建一个RESTTemplatebean,并将我们的自定义拦截器提供给它,但我的问题是,通过这样做,我阻止了其他团队(将使用此初学者)使用他们自己的RestTemplate配置,因为他们必须定义同一个bean,从而导致存在多个bean

@Bean
public RestTemplate restTemplate(){
  RestTemplate restTemplate = new RestTemplate();
  List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
  if (interceptors.isEmpty()){
    interceptors = new ArrayList<>();
  }
  interceptors.add(clientCredentialsAuthInterceptor());
  restTemplate.setInterceptors(interceptors);
  return restTemplate;
}
@Bean
公共RestTemplate RestTemplate(){
RestTemplate RestTemplate=新RestTemplate();
List interceptors=restemplate.getInterceptors();
if(interceptors.isEmpty()){
拦截器=新的ArrayList();
}
add(clientCredentialAuthInterceptor());
restTemplate.setInterceptors(拦截器);
返回REST模板;
}

是否有其他方法可以拦截所有传出请求或进一步配置RestTemplate?

未测试,但它可能会为您提供一个起点:

// Create an interface that users of your dependency 
// can implement which provides interceptors
public interface RestTemplateAuthInterceptorProvider {

  // This interface provides interceptors, so they can add as many as they want
  List<ClientHttpRequestInterceptor> provideInterceptor();
}

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
// define a conditional default implementation of your interceptor provider
@Bean
@ConditionalOnMissingBean(RestTemplateAuthInterceptorProvider.class)
public RestTemplateAuthInterceptorProvider restTemplateAuthInterceptorProvider() {
  return () -> ... // implement your auth interceptor and return
}

// In your actual rest template creation use method argument injection
// If other teams implement the RestTemplateAuthInterceptorProvider interface
// conditional case above will be false and your implementation will not interfere
// If they dont implement RestTemplateAuthInterceptorProvider
// your default implementation will be here
@Bean
public RestTemplate restTemplate(RestTemplateAuthInterceptorProvider provider) {
  RestTemplate restTemplate = new RestTemplate();
  List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
  if (interceptors == null){
    interceptors = new ArrayList<>();
  }
  interceptors.addAll(provider.provideInterceptor()); // from argument 
  restTemplate.setInterceptors(interceptors);
  return restTemplate;
}
//创建一个接口,让依赖项的用户
//可以实现提供拦截器的
公共接口RestTemplateAuthInterceptorProvider{
//此接口提供拦截器,因此它们可以添加任意数量的拦截器
列出ProviderInterceptor();
}
导入org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
//定义拦截器提供程序的条件默认实现
@豆子
@ConditionalOnMissingBean(RestTemplateAuthInterceptorProvider.class)
公共RestTemplateAuthInterceptorProvider RestTemplateAuthInterceptorProvider(){
return()->……//实现auth拦截器并返回
}
//在实际的rest模板创建中,使用方法参数注入
//如果其他团队实现RestTemplateAuthInterceptorProvider接口
//上面的条件case将为false,并且您的实现不会干扰
//如果他们不实现RestTemplateAuthInterceptorProvider
//您的默认实现将在这里
@豆子
公共RestTemplate RestTemplate(RestTemplateAuthInterceptorProvider提供程序){
RestTemplate RestTemplate=新RestTemplate();
List interceptors=restemplate.getInterceptors();
if(拦截器==null){
拦截器=新的ArrayList();
}
interceptors.addAll(provider.providedinterceptor());//来自参数
restTemplate.setInterceptors(拦截器);
返回REST模板;
}
编辑: 另一种黑客方法是操作已经定义的RESTTemplatebean

@Component
@ConditionalOnBean(RestTemplate.class)
public class RestTemplateBeanCustomizer {

  private List<RestTemplate> restTemplateBeans;

  // This injects all restTemplate bean definitions to your bean as a list
  @Autowired
  public RestTemplateBeanCustomizer(List<RestTemplate> restTemplateBeans) {
    this.restTemplateBeans = restTemplateBeans;
  }

  @PostConstruct
  public void customizeRestTemplateBeans() {
      for (RestTemplate restTemplate : restTemplateBeans) {
        // Add your interceptors message handlers etc
        // restTemplate.set...
      }
  }
}
@组件
@ConditionalOnBean(RestTemplate.class)
公共类RestTemplateBeanCustomizer{
私有列表restTemplateBeans;
//这会将所有RESTTemplatebean定义作为列表注入到bean中
@自动连线
公共RestTemplateBeanCustomizer(列出restTemplateBeans){
this.restTemplateBeans=restTemplateBeans;
}
@施工后
public void customizeRestTemplateBeans(){
for(RestTemplate RestTemplate:restTemplateBeans){
//添加拦截器、消息处理程序等
//restTemplate.set。。。
}
}
}

如果我说的没错,这只允许他们定义自己的自定义拦截器。我的问题更多的是关于创建RestTemplate本身。假设他们想向其中添加一个定制的messageHandler,但是初学者已经定义了一个没有这个的bean。我可以用@ConditionalOnMissingBean对它进行注释,但是如果有人定义了它,就不会设置拦截器。我编辑了我的答案。理想情况下,您的项目应该使用
RestTemplateBuilder
创建
RestTEmplate
的实例,这反过来会自动检测所有预注册的拦截器。autp配置所要做的唯一一件事就是为拦截器生成一个bean。或者定义一个添加拦截器的
restemplatecustomizer
。但是,只有当团队遵循使用
restemplatebuilder
创建实例的实践时,这才有效。