在Feign客户端+ Spring云(Brixton RC 2)中使用具有动态值的@Headers

2nc8po8w  于 2022-12-17  发布在  Spring
关注(0)|答案(7)|浏览(145)

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

@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的实现会添加标头,但无法动态设置标头值

@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
此致

nx7onnlm

nx7onnlm1#

解决方案是使用@RequestHeader注解,而不是伪造特定的注解

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

qxsslcnc2#

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

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

64jmpszr3#

@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());
0sgqnhkj

0sgqnhkj4#

我有这个例子,我使用@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);

}
3z6pesqy

3z6pesqy5#

您可以使用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;
}
ff29svar

ff29svar6#

我使用@HeaderMap,因为如果你使用Open feign,它看起来非常方便。使用这种方式,你可以动态地传递头键和值。

@Headers({"Content-Type: application/json"})
public interface NotificationClient {

    @RequestLine("POST")
    String notify(URI uri, @HeaderMap Map<String, Object> headers, NotificationBody body);
}

现在创建伪REST客户机来调用服务端点,创建头属性Map并将其传入方法参数。

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());
66bbxpm5

66bbxpm57#

现在讲这个有点晚了,但是如果需要一个强制的、模板化的值,我发现这在 Boot 中是有效的,显然,只要toString()给出一个有效的头值,就可以使用任何类型。

@FeignClient(
    name = "my-feign-client",
    url = "http://my-url.com"
)
public interface MyClient {
    @GetMapping(
        path = "/the/endpoint",
        produces = MediaType.APPLICATION_JSON_VALUE
    )
    DataResponse getData(@RequestHeader(HttpHeaders.AUTHORIZATION) BearerHeader bearerHeader);
final class BearerHeader {
    private final String token;

    private BearerHeader(String token) {
        this.token = token;
    }

    @Override
    public String toString() {
        return String.format("Bearer %s", token);
    }

    public static BearerHeader of(String token) {
        return new BearerHeader(token);
    }
}

相关问题