我定义了一个 REST 接口,它具有不同的 Spring Boot 应用程序实现,使用不同的实现spring.application.name(spring.application.name在我的业务中不能相同)。
如何只定义一个Feign Client,并且可以访问所有SpringBootApplication REST服务?
SpringBootApplication A(spring.application.name=A) 和 B(spring.application.name=) 有这个 RestService:
@RestController
@RequestMapping(value = "/${spring.application.name}")
public class FeignRestService {
@Autowired
Environment env;
@RequestMapping(path = "/feign")
public String feign() {
return env.getProperty("server.port");
}
}
Run Code Online (Sandbox Code Playgroud)
另一个 SpringBootApplication C:
@FeignClient(name="SpringApplication A or B")
public interface FeignClientService {
@RequestMapping(path = "/feign")
public String feign();
}
Run Code Online (Sandbox Code Playgroud)
在SpringBootApplication C中,我想使用FeignClientService来访问A和B。你有什么想法吗?
spring-boot spring-cloud-feign feign netflix-ribbon spring-cloud-netflix
我正在尝试使用 spring cloud feign 创建一个简单的 REST 客户端来使用使用 OAuth2 安全令牌保护的服务。我正在使用 OAuth2FeignRequestInterceptor 添加不记名令牌,请检查下面的代码。我面临 401。当尝试调试我的代码时,我在请求对象中找不到不记名令牌。
@Configuration
@EnableConfigurationProperties(value=OAuth2ClientCredentialsProperties.class)
@EnableOAuth2Client
@Profile(OAuth2Profiles.CLIENT_CREDENTIALS)
public class ClientCredentialsConfiguration {
@Autowired
private OAuth2ClientCredentialsProperties oAuth2ClientCredentialsProperties;
@Bean
@Qualifier("ClientCredentialsOAuth2FeignRequestInterceptor")
public OAuth2FeignRequestInterceptor oauth2schemeRequestInterceptor() {
return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), oauth2schemeResourceDetails());
}
@Bean
public ClientCredentialsResourceDetails oauth2schemeResourceDetails() {
ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();
details.setClientId(oAuth2ClientCredentialsProperties.getClientId());
details.setClientSecret(oAuth2ClientCredentialsProperties.getClientSecret());
details.setAccessTokenUri(oAuth2ClientCredentialsProperties.getAccessTokenUri());
details.setScope(oAuth2ClientCredentialsProperties.getScopes());
return details;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的客户端界面
@FeignClient(name = "test", url = "http://localhost:8080", configuration = ClientCredentialsConfiguration.class)
interface GitHubClient {
@RequestMapping(value = "/api/v1/products",
produces = "application/json",
consumes = "application/json;charset=UTF-8",
method = RequestMethod.POST)
ResponseEntity<Object> …Run Code Online (Sandbox Code Playgroud) spring-boot spring-security-oauth2 spring-cloud-feign spring-cloud-netflix
我目前有两个服务正在 Eureka 服务器上注册,分别为 RESTAURANT 和 MENU。

这些名称在每个服务的 boostrap.yml 文件中定义为:
spring:
application:
name: menu
Run Code Online (Sandbox Code Playgroud)
然而,当涉及到使用Netflix的Feign时,我在注释中输入应用程序名称,如下所示:
@FeignClient("MENU")
public interface MenuClient {
@RequestMapping(value = "/restaurants/{restaurantId}/menu", method = RequestMethod.GET, consumes = "application/json")
public Menu getMenu(@PathVariable("restaurantId") final Long restaurantId);
}
Run Code Online (Sandbox Code Playgroud)
这最终导致 URL 没有映射到 eureka 服务,而是映射到http://MENU。

我确认,如果我在注释中对 url 进行硬编码,那么假客户端可以工作,但这会阻止我为我的服务生成随机端口。
我在这里缺少什么?该假冒客户位于 RESTAURANT 服务中。
我的餐厅服务主课
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class RestaurantApplication {
public static void main(String[] args) {
SpringApplication.run(RestaurantApplication.class, args);
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试让Spring Cloud Netflix Feign客户端通过 HTTP 获取一些 JSON 并将其转换为对象。我不断收到此错误:
org.springframework.web.client.RestClientException:无法提取响应:没有找到适合响应类型 [class io.urig.checkout.Book] 和内容类型 [application/json;charset=UTF-8] 的 HttpMessageConverter
以下是从远程服务返回的 JSON 内容:
{
"id": 1,
"title": "Moby Dick",
"author": "Herman Melville"
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试反序列化的相应类:
package io.urig.checkout;
public class Book {
private long id;
private String title;
private String author;
public Book() {}
public Book(long id, String title, String author) {
super();
this.id = id;
this.title = title;
this.author = author;
}
public long getId() {
return id;
}
public void setId(long id) { …Run Code Online (Sandbox Code Playgroud) 我在尝试反序列化包含 LocalDateTime 字段的 JSON POST 响应时遇到异常。
feign.codec.DecodeException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING
Run Code Online (Sandbox Code Playgroud)
以下是 JSON 格式的响应:
{
"date":"2018-03-18 01:00:00.000"
}
Run Code Online (Sandbox Code Playgroud)
这就是我创建远程服务的方式:
@PostConstruct
void createService() {
remoteService = Feign.builder()
.decoder(new GsonDecoder())
.encoder(new GsonEncoder())
.target(RemoteInterface.class, remoteUrl);
}
Run Code Online (Sandbox Code Playgroud)
如何强制 Feign 将日期反序列化为 LocalDateFormat?
我有一个 aop 设置
@Target({ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface IgnoreHttpClientErrorExceptions { }
@Aspect
@Component
public class IgnoreHttpWebExceptionsAspect {
@Around(value = "@annotation(annotation)", argNames = "joinPoint, annotation")
public Object ignoreHttpClientErrorExceptions(ProceedingJoinPoint joinPoint, IgnoreHttpClientErrorExceptions annotation)
throws Throwable {
try {
//do something
} catch (HttpClientErrorException ex) {
//do something
}
}
Run Code Online (Sandbox Code Playgroud)
如果我@IgnoreHttpClientErrorExceptions在服务层添加这个注释(),
@Service
public class SentenceServiceImpl implements SentenceService {
@Autowired
VerbClient verbClient;
@HystrixCommand(ignoreExceptions = {HttpClientErrorException.class})
@IgnoreHttpClientErrorExceptions
public ResponseEntity<String> patch(String accountId, String patch) {
return verbClient.patchPreferences(accountId, patch);
}
}
Run Code Online (Sandbox Code Playgroud)
我的AOP被调用了。
@IgnoreHttpClientErrorExceptions但是当我在我的 feign …
在我们的项目中,我们使用 feign client 调用第三方服务。对于内容类型 application/json,它工作正常。但是我们有一个要求,第三方服务 URL 返回 pdf 文件,而那个时候我们遇到了异常。
由于安全原因,我无法粘贴日志和代码,但是如果有人与我分享从 feign 客户端下载 pdf 文件的代码,那将对我非常有帮助。
提前致谢!!
我们在应用程序中使用 Open Feign,该应用程序在 Spring Boot 2.0.6 和 Spring Cloud Finchley.SR2 上运行。
我们需要所有 Feign 客户端在每次调用的标头中添加来自安全上下文的令牌,因此我们创建了一个配置,它为所有客户端生成一个全局拦截器:
@Configuration
@Import({FeignClientsConfiguration.class})
public class FeignConfig {
@Value("${a.spring.config}")
private int minTokenLifespan;
@Autowired
private OAuthContext oAuthContext;
@Autowired
private AuthManager authManager;
@Bean
public RequestInterceptor myCustomInterceptor() {
return new CustomInterceptor(oAuthContext, authManager, minTokenLifespan);
}
}
Run Code Online (Sandbox Code Playgroud)
该拦截器适用于除一个之外的所有 Feign 客户端。在调试器中我们可以看到,在类中创建 Bean之前,创建了这个特殊的 feign 客户端(及其 SynchronousMessageHandler)FeignConfig。仅在第一个 Feign 客户端之后创建CustomIntercepter,所有其他客户端都是在之后创建的,知道拦截器的存在并将应用它。
我们该如何调试这个问题呢?过去有人遇到过不同的问题吗?
我无法发布生产代码,但我很乐意回答任何问题并尝试发布混淆的代码。
我有一个调用远程服务的 Spring Boot 应用程序。
这个远程 Web 服务为我提供了一个 p12 文件,该文件应该验证我的应用程序。
如何配置我的 feign 客户端以使用 p12 证书?
我尝试过设置这些属性:
-Djavax.net.ssl.keyStore=path_to_cert.p12 -Djavax.net.ssl.keyStorePassword=xxx -Djavax.net.ssl.keyStoreType=PKCS12
Run Code Online (Sandbox Code Playgroud)
但这并没有改变任何东西,我仍然收到此错误:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Run Code Online (Sandbox Code Playgroud) 我正在尝试在 Spring Boot 应用程序的测试中为 Spock 测试设置 feign 客户端。
Spock 测试设置为
@ActiveProfiles("functional-test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Run Code Online (Sandbox Code Playgroud)
我有一个 application-function-test.yml ,其中我的 feign 客户端是 url 定义,我尝试过:
my.feign.client.example.url: localhost:${local.server.port}
Run Code Online (Sandbox Code Playgroud)
但本地服务器端口显示为 0,这不适合应用程序的随机端口。
我也尝试过,其中 randomServerPort 包含随机端口,但我无法覆盖该属性:
@LocalServerPort
int randomServerPort;
@Value('${my.feign.client.example.url}')
String feignTestClient
void setup() {
feignTestClient="localhost:${randomServerPort}"
}
Run Code Online (Sandbox Code Playgroud)
有什么最佳实践的想法吗?我更喜欢在 application-function-test.yml 中设置 url,这样可以避免使用虚拟值进行初始化
我的 Feign 客户端如下所示:
@FeignClient(name = "myClient", url = "${my.feign.client.example.url}")
public interface FeignTestRestClient extends SomeControllerApi {}
Run Code Online (Sandbox Code Playgroud) spring-boot ×6
spring ×4
java ×3
feign ×2
spring-cloud ×2
aspectj ×1
date ×1
localdate ×1
spock ×1
spring-aop ×1