|
|
|
@ -246,6 +246,78 @@ client.xml("denominator", "secret"); // <login "user_name"="denominator" "passwo
@@ -246,6 +246,78 @@ client.xml("denominator", "secret"); // <login "user_name"="denominator" "passwo
|
|
|
|
|
client.json("denominator", "secret"); // {"user_name": "denominator", "password": "secret"} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
### Headers |
|
|
|
|
Feign supports settings headers on requests either as part of the api or as part of the client |
|
|
|
|
dending on the use case. |
|
|
|
|
|
|
|
|
|
#### Set headers using apis |
|
|
|
|
In cases where specific interfaces or calls should always have certain header values set, it |
|
|
|
|
makes sense to define headers as part of the api. |
|
|
|
|
|
|
|
|
|
Static headers can be set on an api interface or method using the `@Headers` annotation. |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
@Headers("Accept: application/json") |
|
|
|
|
interface BaseApi<V> { |
|
|
|
|
@Headers("Content-Type: application/json") |
|
|
|
|
@RequestLine("PUT /api/{key}") |
|
|
|
|
void put(@Param("key") String, V value); |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Methods can specify dynamic content for static headers using using variable expansion in `@Headers`. |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
@RequestLine("POST /") |
|
|
|
|
@Headers("X-Ping: {token}") |
|
|
|
|
void post(@Param("token") String token); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
These approaches specify specific header entries as part of the api without requiring any customizations |
|
|
|
|
when buildling Feing clients. It is not currently possible to customize the header entries themselves |
|
|
|
|
on a per-request basis at the api level. |
|
|
|
|
|
|
|
|
|
#### Setting headers per target |
|
|
|
|
In cases where headers should differ for the same api based on different endpoints or where per-request |
|
|
|
|
customization is required, headers can be set as part of the client using a `RequestInterceptor` or a |
|
|
|
|
`Target`. |
|
|
|
|
|
|
|
|
|
For an example of setting headers using a `RequestInterceptor`, see the `Request Interceptors` section. |
|
|
|
|
|
|
|
|
|
Headers can be set as part of a custom `Target`. |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
static class DynamicAuthTokenTarget<T> implements Target<T> { |
|
|
|
|
public DynamicAuthTokenTarget(Class<T> clazz, |
|
|
|
|
UrlAndTokenProvider provider, |
|
|
|
|
ThreadLocal<String> requestIdProvider); |
|
|
|
|
... |
|
|
|
|
@Override |
|
|
|
|
public Request apply(RequestTemplate input) { |
|
|
|
|
TokenIdAndPublicURL urlAndToken = provider.get(); |
|
|
|
|
if (input.url().indexOf("http") != 0) { |
|
|
|
|
input.insert(0, urlAndToken.publicURL); |
|
|
|
|
} |
|
|
|
|
input.header("X-Auth-Token", urlAndToken.tokenId); |
|
|
|
|
input.header("X-Request-ID", requestIdProvider.get()); |
|
|
|
|
|
|
|
|
|
return input.request(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
... |
|
|
|
|
Bank bank = Feign.builder() |
|
|
|
|
.target(new DynamicAuthTokenTarget(Bank.class, provider, requestIdProvider)); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
These approaches depend on the custom `RequestInterceptor` or `Target` being set on the Feign |
|
|
|
|
client when it is built and can be used as a way to set headers on all api calls on a per-client |
|
|
|
|
basis. This can be useful for doing things such as setting an authentication token in the header |
|
|
|
|
of all api requests on a per-client basis. The methods are run when the api call is made on the |
|
|
|
|
thread that invokes the api call, which allows the headers to be set dynamically at call time and |
|
|
|
|
in a context-specific manner -- for example, thread-local storage can be used to set different |
|
|
|
|
header values depending on the invoking thread, which can be useful for things such as setting |
|
|
|
|
thread-specific trace identifiers for requests. |
|
|
|
|
|
|
|
|
|
### Advanced usage |
|
|
|
|
|
|
|
|
|
#### Base Apis |
|
|
|
|