具有不同拦截器的多个 Feign 客户端

问题描述 投票:0回答:2

我有两个 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 发生冲突。)

java spring-boot feign
2个回答
4
投票

我想你必须消除刻板印象

@Configuration

我实际上是在搜索类似问题时来到这里的。我确实有(和你一样)两个不同的配置。一个 FeignClient 有身份验证,第二个客户端没有身份验证。但第二个客户端正在使用两个 RequestInterceptor (我实现了一个 noop-RequestInterceptor 只是为了日志记录)。

你真的能解决你的问题吗?


0
投票

尝试删除

@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

© www.soinside.com 2019 - 2024. All rights reserved.