springboot feign 使用很方便, 只需要编写接口即可使用, 但是有时候需要登录绑定token, 每次手动传入token header 太不方便
可以通过target 配置,传入token
在配置文件中
@Inject
HttpService httpService; //用来获取token
@Inject
private Properties properties; //登录的账号密码等配置
@Bean
public Feign.Builder builder() {
log.debug("default builder for external feign client");
return new FeignBuilder(httpService, properties);
}
写一个FeignBuilder
public class FeignBuilder extends Feign.Builder {
private HttpService httpService;
private Properties properties;
public MfgFeignBuilder(HttpService httpService, Properties properties) {
this.httpService= httpService;
this.properties= properties;
}
@Override
public <T> T target(Target<T> target) {
MfgTarget<T> mfgTarget = new MfgTarget<>(target, httpService, properties);
return super.target(mfgTarget);
}
}
重点, 写一个target
public class MfgTarget<T> implements Target<T> {
private static final String AUTHENTICATE_REQUEST_URL = "/mfg-uaa/oauth/token?grant_type=client_credentials";
private Target<T> wrappedTarget;
private TenantService tenantService;
private MfgProperties mfgProperties;
public MfgTarget(Target<T> wrappedTarget, TenantService tenantService, MfgProperties mfgProperties) {
this.wrappedTarget = wrappedTarget;
this.tenantService = tenantService;
this.mfgProperties = mfgProperties;
}
@Override
public Class<T> type() {
return wrappedTarget.type();
}
@Override
public String name() {
return wrappedTarget.name();
}
@Override
public String url() {
return wrappedTarget.url();
}
@Override
public Request apply(RequestTemplate input) {
if (input.url().indexOf("http") != 0) {
input.target(url());
final Map<String, Collection<String>> headers = input.headers();
if (input.url().contains(AUTHENTICATE_REQUEST_URL)) {
return input.request();
}
final String accessToken = tenantService.getAccessToken(tenantInfo.getId(), tenantInfo.getPassword(), tenant);
input.header(Contants.AUTHORIZATION, accessToken);
}
return input.request();
}
}
这样, 每次请求的时候, 都会去tenantService中获取token, 如果没有则进行登录, 当然缓存token的逻辑存储在tenantService中了
网友评论