Roc*_*der 5 rest spring-boot netflix-feign spring-cloud-feign feign
无法让Feign客户工作。首先尝试使用POST。保持与编码器/解码器有关的错误,指出类型不正确。然后在github上找到一个示例来最终调用简单的GET API,并决定尝试一下。仍然失败
在Github和在线上,我看到Feign Client Spring-Cloud,OpenFeign,Netflix.feign的多个版本具有不同的版本。谁能形容一个最好的,稳定的Feign客户应该用于生产什么?
package com.paa.controllers;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient (name="test-service",url="https://www.reddit.com/r")
public interface GetFeignClient {
@RequestMapping(method = RequestMethod.GET, value = "/java.json")
public String posts();
}
Controller:
@RestController
@RequestMapping("/some/api")
public class TestWLCController {
@Autowired
private GetFeignClient getFeignClient;
.. some stuff
@RequestMapping(value="/postSomething",method = RequestMethod.POST)
@ApiOperation(value = "Configures something",
notes = "basic rest controller for testing feign")
public ResponseEntity<SomeResponse> feignPost(
UriComponentsBuilder builder,
@ApiParam(name = "myRequest",
value = "request for configuring something",
required = true)
@Valid @RequestBody SomeRequest someRequest) {
String resp = null;
try {
resp = getFeignClient.posts();
} catch (Exception er) {
er.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
应用:
尝试了所有可能的注释排列方式,认为它将解决AutoWire问题,但仍然失败
@Configuration
@ComponentScan
@EnableAutoConfiguration
//@EnableEurekaClient
@EnableFeignClients
//@SpringBootApplication
//@EnableFeignClients
//@EnableFeignClients(basePackages = {"com.paa.xenia.controllers", "com.paa.xenia.services"})
public class ServiceApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(XeniaServiceApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
2016-07-20 18:15:42.406 [0; 39m [31mERROR [0; 39m [35m32749 [0; 39m [2m --- [0; 39m [2m [main]] [0; 39m [36mo.s.boot .SpringApplication [0; 39m [2m:[0; 39m应用程序启动失败
org.springframework.beans.factory.BeanCreationException:创建名称为'testWLCController'的bean时出错:自动连接依赖项的注入失败;嵌套的异常是org.springframework.beans.factory.BeanCreationException:无法自动连线字段:私有com.paa.controllers.GetFeignClient com.paa.controllers.TestWLCController.gfClient; 嵌套的异常是org.springframework.beans.factory.BeanCreationException:创建名称为'com.aa..controllers.GetFeignClient'的bean时出错:FactoryBean在对象创建时抛出了异常;嵌套的异常是org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]处的java.lang.NullPointerException org。在com.paa.ServiceApplication.main(ServiceApplication.java:44)处运行(SpringApplication.java:1180)[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] [bin /:na]由:org.springframework.beans.factory.BeanCreationException:无法自动连线字段:私有com.paa.controllers.GetFeignClient com.paa.controllers.TestWLCController.gfClient; 嵌套的异常是org.springframework.beans.factory.BeanCreationException:创建名称为'com.paa.controllers.GetFeignClient'的bean时出错:FactoryBean在对象创建时抛出了异常;嵌套的异常是org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573)上的java.lang.NullPointerException〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE ],网址为org.springframework.beans。
我不确定您最终是否自己弄清楚了,但为了其他可能偶然发现此线程的人,下面是您尝试执行的操作的示例。我将首先指出代码中不正确或至少不需要的一些内容,然后展示我的代码是否有效。
url属性。<feign client name>.ribbon.listOfServers相反,请使用in bootstrap.yml(或)设置服务器列表bootstrap.properties。这允许客户端负载平衡,因为listOfServers可以是逗号分隔的列表。listOfServers和的一部分<feign client name>.ribbon.IsSecure: true。如果没有该端口,则将连接到端口 80;如果没有该端口IsSecure,则使用 HTTP。使用 进行测试curl,我发现 Reddit 需要很长时间才能响应。有关如何分解请求-响应周期所花费的总时间的详细信息,请参阅此 SO帖子。
$ curl -v -H "User-Agent: Mozilla/5.0" -w "@curl-format.txt" -o /dev/null -s "https://www.reddit.com/r/java/top.json?count=1"
{ [2759 bytes data]
* Connection #0 to host www.reddit.com left intact
time_namelookup: 0.527
time_connect: 0.577
time_appconnect: 0.758
time_pretransfer: 0.758
time_redirect: 0.000
time_starttransfer: 11.189
----------
time_total: 11.218
Run Code Online (Sandbox Code Playgroud)根据 Netflix Wiki,默认的读取和连接超时为 3000 毫秒,因此除非您更改这些设置,否则您将始终超时。
User-Agent在curl请求中指定了标头。这是因为 Reddis 似乎对此非常挑剔,如果未指定,大多数时候都会返回 HTTP 429“请求过多”。它们不会Retry-After在响应中返回标头,因此无法告诉您在发出另一个请求之前需要等待多长时间。“空谈是廉价的。给我看看代码。” (莱纳斯·托瓦兹 (2000-08-25))。
我使用优秀的Spring Initializr站点生成了一个 Gradle 应用程序。这是该文件的一个片段build.gradle。
dependencies {
compile('org.springframework.cloud:spring-cloud-starter-feign')
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Camden.SR3"
}
}
Run Code Online (Sandbox Code Playgroud)
假冒客户:
@FeignClient(name = "reddit")
public interface RedditClient {
@RequestMapping(method = GET, value = "/r/java/top.json?count=1",
headers = {USER_AGENT + "=Mozilla/5.0", ACCEPT + "=" + APPLICATION_JSON_VALUE})
public String posts();
}
Run Code Online (Sandbox Code Playgroud)
启动应用程序:
@SpringBootApplication
@EnableFeignClients
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@RestController
static class DemoController {
@Autowired
private RedditClient redditClient;
@GetMapping("/posts")
public String posts() {
return redditClient.posts();
}
}
}
Run Code Online (Sandbox Code Playgroud)
bootstrap.yml:
reddit:
ribbon:
listOfServers: www.reddit.com:443
ConnectTimeout: 20000
ReadTimeout: 20000
IsSecure: true
hystrix.command.default.execution:
timeout.enabled: true
isolation.thread.timeoutInMilliseconds: 50000
Run Code Online (Sandbox Code Playgroud)
集成测试:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoApplicationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testGetPosts() {
ResponseEntity<String> responseEntity = restTemplate.getForEntity("/posts", String.class);
HttpStatus statusCode = responseEntity.getStatusCode();
assertThat(String.format("Actual status code: %d, reason: %s.",
statusCode.value(), statusCode.getReasonPhrase()),
statusCode.is2xxSuccessful(), equalTo(true));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19014 次 |
| 最近记录: |