【问题标题】:Using @Headers with dynamic values in Feign client + Spring Cloud (Brixton RC2)在 Feign 客户端 + Spring Cloud (Brixton RC2) 中使用带有动态值的 @Headers
【发布时间】:2016-09-01 04:04:56
【问题描述】:

是否可以为标题设置动态值?

@FeignClient(name="Simple-Gateway")
interface GatewayClient {
    @Headers("X-Auth-Token: {token}")
    @RequestMapping(method = RequestMethod.GET, value = "/gateway/test")
        String getSessionId(@Param("token") String token);
    }

注册一个RequestInterceptor的实现会添加header但是没有办法动态设置header值

@Bean
    public RequestInterceptor requestInterceptor() {

        return new RequestInterceptor() {

            @Override
            public void apply(RequestTemplate template) {

                template.header("X-Auth-Token", "some_token");
            }
        };
    } 

我在 github 上发现了以下问题,其中一位评论者 (lpborges) 正在尝试使用 @RequestMapping 注释中的标头做类似的事情。

https://github.com/spring-cloud/spring-cloud-netflix/issues/288

亲切的问候

【问题讨论】:

    标签: spring spring-cloud spring-cloud-netflix


    【解决方案1】:

    您可以使用 HttpHeaders。

    @PostMapping(path = "${path}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    ResponseEntity<?> callService(@RequestHeader HttpHeaders headers, @RequestBody Object object);
    
    private HttpHeaders getHeaders() {
      HttpHeaders headers = new HttpHeaders();
    
      headers.add("Authorization", "1234");
      headers.add("CLIENT_IT", "dummy");
      return headers;
    }
    

    【讨论】:

      【解决方案2】:

      @HeaderMap、@Header 和 @Param 对我不起作用,下面是使用 FeignClient 传递多个标头参数时使用 @RequestHeader 的解决方案

      @PostMapping("/api/channelUpdate")
      EmployeeDTO updateRecord(
            @RequestHeader Map<String, String> headerMap,
            @RequestBody RequestDTO request);
      

      调用代理的代码如下:

      Map<String, String> headers = new HashMap<>();
      headers.put("channelID", "NET");
      headers.put("msgUID", "1234567889");
      ResponseDTO response = proxy.updateRecord(headers,requestDTO.getTxnRequest());
      

      【讨论】:

        【解决方案3】:

        我使用@HeaderMap,因为如果您使用Open feign,它似乎非常方便。使用这种方式,您可以动态传递标题键和值。

        @Headers({"Content-Type: application/json"})
        public interface NotificationClient {
        
            @RequestLine("POST")
            String notify(URI uri, @HeaderMap Map<String, Object> headers, NotificationBody body);
        }
        

        现在创建 feign REST 客户端来调用服务端点,创建你的头部属性映射并将其传递给方法参数。

        NotificationClient notificationClient = Feign.builder()
            .encoder(new JacksonEncoder())
            .decoder(customDecoder())
            .target(Target.EmptyTarget.create(NotificationClient.class));
        
        Map<String, Object> headers = new HashMap<>();
        headers.put("x-api-key", "x-api-value");
        
        ResponseEntity<String> response = notificationClient.notify(new URI("https://stackoverflow.com/example"), headers, new NotificationBody());
        

        【讨论】:

        • 那么,这张包含动态数据的地图来自哪里?
        • @WesternGun 我添加了一个示例如何使用具有动态标题属性的 feign 客户端
        • OK 所以使用 OpenFeign 构建器。这使它更清楚。谢谢。
        【解决方案4】:

        @RequestHeader 对我不起作用。起作用的是:

        @Headers("X-Auth-Token: {access_token}")
        @RequestLine("GET /orders/{id}")
        Order get(@Param("id") String id, @Param("access_token") String accessToken);
        

        【讨论】:

        • @RequestHeader 是一个 Spring 注解,@Headers + @Param 应该在使用 OpenFeign 时使用。
        【解决方案5】:

        我有这个例子,我用 @HeaderParam 代替 @RequestHeader :

        import rx.Single;
        
        import javax.ws.rs.Consumes;
        import javax.ws.rs.HeaderParam;
        import javax.ws.rs.POST;
        import javax.ws.rs.Path;
        import javax.ws.rs.core.HttpHeaders;
        import javax.ws.rs.core.MediaType;
        
        
        @Consumes(MediaType.APPLICATION_JSON)
        public interface  FeignRepository {
        
          @POST
          @Path("/Vehicles")
          Single<CarAddResponse> add(@HeaderParam(HttpHeaders.AUTHORIZATION) String authorizationHeader, VehicleDto vehicleDto);
        
        }
        

        【讨论】:

          【解决方案6】:

          解决方法是使用@RequestHeader注解,而不是feign特定的注解

          @FeignClient(name="Simple-Gateway")
          interface GatewayClient {    
              @RequestMapping(method = RequestMethod.GET, value = "/gateway/test")
              String getSessionId(@RequestHeader("X-Auth-Token") String token);
          }
          

          【讨论】:

          • @RequestHeader 在与 Feign 一起使用时似乎忽略了它的 requireddefaultValue 参数。
          猜你喜欢
          • 2016-08-31
          • 2020-01-27
          • 2017-01-22
          • 2019-01-26
          • 2016-12-01
          • 2021-10-22
          • 2016-05-11
          • 2018-02-11
          • 2020-11-27
          相关资源
          最近更新 更多