我有两个 Feign 客户端在 Spring Boot 中执行不同的操作,但希望对它们进行不同的身份验证。
@FeignClient(
name = "...",
url = "${url1}",
configuration = Config1.class
)
public interface Client1 {
@PostMapping(
path = "...",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
JsonNode doThing(@RequestBody JsonNode thing);
}
@FeignClient(
name = "...",
url = "${url2}",
configuration = Config2.class
)
public interface Client2 {
@PostMapping(
path = "...",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
JsonNode doThing(@RequestBody JsonNode thing);
}
它们都需要基本身份验证,但用户名和密码的值不同。为此,我考虑使用单独的
Config
类来设置各自的客户端:
@Configuration
public class Client1 {
private final String user;
private final String password;
public Client1(final Config1 config) {
this.user = config.getUser();
this.password = config.getPassword();
}
@Bean(name = "client1")
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor(user, password);
}
}
@Configuration
public class Client2 {
private final String user;
private final String password;
public Client1(final Config2 config) {
this.user = config.getUser();
this.password = config.getPassword();
}
@Bean(name = "client2")
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor(user, password);
}
}
但是我的 API 返回 HTTP 4xx 错误,就好像拦截器根本不起作用一样。我可以获得一些有关正确设置的指导吗?
(请注意,我给了这些 bean
name
,因为否则它们会与 DI 发生冲突。)
我想你必须消除刻板印象
@Configuration
。
我实际上是在搜索类似问题时来到这里的。我确实有(和你一样)两个不同的配置。一个 FeignClient 有身份验证,第二个客户端没有身份验证。但第二个客户端正在使用两个 RequestInterceptor (我实现了一个 noop-RequestInterceptor 只是为了日志记录)。
你真的能解决你的问题吗?
尝试删除
@Configuration
注释,并使用 ApplicationContext
读取配置的属性:
// config
import feign.RequestInterceptor;
import feign.auth.BasicAuthRequestInterceptor;
import org.springframework.context.annotation.Bean;
public class Client1 {
@Bean(name = "amapRequestInterceptor")
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
String user = SpringUtils.getProperty("client1.user", String.class, null);
String password = SpringUtils.getProperty("client1.password", String.class, null);
return new BasicAuthRequestInterceptor(user, password);
}
}
// SpringUtils
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
if (SpringUtils.applicationContext == null) {
SpringUtils.applicationContext = applicationContext;
}
}
public static <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
return applicationContext.getEnvironment().getProperty(key, targetType, defaultValue);
}
}
代码中的问题是假装会在应用程序上下文中使用所有
RequestInterceptor
,以便Authorization
标头被覆盖两次。
删除
@Configuration
后,应用程序上下文中没有RequestInterceptor,feign将使用RequestInterceptor
指定的@FeignClient
。