首页 文章

无法让Feign客户端为基本示例工作

提问于
浏览
3

无法让Feign客户端工作 . 首先尝试使用POST . 保持运行与编码器/解码器相关的错误说类型不正确 . 然后在github上找到一个例子,最后调用简单的GET API并决定试一试 . 仍然失败

在Github和网上,我看到Feign Client Spring-Cloud,OpenFign,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();
        }

    }
}

应用:

尝试了所有可能的注释排列,认为它可以解决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);
    }
}

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:无法自动装配字段:private com.paa.controllers.GetFeignClient com.paa.controllers.TestWLCController.gfClient;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'com.aa..controllers.GetFeignClient'的bean时出错:FactoryBean在创建对象时抛出异常;嵌套异常是java.lang.NullPointerException,位于org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java: 482)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:306)〜[spring-beans- 4.2.6.RELEASE.jar:4.2.6.RELEASE]在org.springframework.beans.fa org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory)中的ctory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] .java:302)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)〜[spring- bean-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)~ [spring-beans-4.2.6.RELEASE.jar :or.6.RELEASE] org.springframework上的org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)〜[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] org.springframework.bo上的.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)〜[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] org.springframework.boot.SpringApplication.refresh(SpringApplication.java)中的ot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)~ [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] :766)[org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)[spring-boot-1.3.5.RELEASE . jar:1.3.5.RELEASE]在org.springframework.boot上的org.springframework.boot.SpringApplication.run(SpringApplication.java:307)[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] .SpringApplication.run(SpringApplication.java:1191)[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)[spring- boot.1.3.5.RELEASE.jar:1.3.5.RELEASE] at com.paa.ServiceApplication.main(ServiceApplication.java:44)[bin /:na]引起:org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private 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上的java.lang.NullPointerException $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)〜[spring-beans-4.2.6 .RELEASE.jar:4.2.6.RELEASE] ...省略了17个com.n帧

2 回答

  • 3

    我不确定你是否最终自己弄清楚了,但是为了其他可能偶然发现这个问题的人,下面是你想要做的事情的一个有效例子 . 我将首先指出一些不正确的,或至少在代码中不需要的东西,然后显示我的代码有效 .

    • 您应该尽量不使用 url 属性 . 而是在 bootstrap.yml (或 bootstrap.properties )中使用 <feign client name>.ribbon.listOfServers 设置服务器列表 . 这允许客户端负载 balancer ,因为 listOfServers 可以是以逗号分隔的列表 .

    • 使用功能区进行HTTPS连接,您需要指定HTTP连接不需要的两件事 . 该端口,是 listOfServers<feign client name>.ribbon.IsSecure: true 的一部分 . 如果没有端口,则连接到端口80,如果没有 IsSecure ,则使用HTTP .

    • 使用 curl 测试,我发现Reddit需要 very 长时间来响应 . 有关如何分解请求 - 响应周期所花费的总时间的详细信息,请参阅此SO post .

    $ 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
    

    根据Netflix Wiki,默认的读取和连接超时为3000毫秒,因此除非您更改,否则您将始终超时 .

    • 您可能已经注意到我在 curl 请求中指定了 User-Agent 标头 . 's because Reddis seems to be very picky about that and if not specified, returns a HTTP 429 710732 most of the times. They don' t在响应中返回一个 Retry-After 标头,因此无法确定在发出另一个请求之前需要等待多长时间 .

    • Spring Cloud Netflix以及Netflix Feign是开源的,因此一些(很多)耐心和调试技巧非常方便 .

    "Talk is cheap. Show me the code."(Torvalds,Linus(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"
        }
    }
    

    Feign client

    @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();
    }
    

    Boot Application

    @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();
            }
        }
    }
    

    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
    

    Integration test

    @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));
        }
    }
    
  • 0

    有人有兴趣了解我们是如何做到这一点所以发布答案为他们的利益 .

    父模块

    package com.cisco.module.base;
    
    @EnableFeignClients
    public abstract class BaseApplication extends SpringBootServletInitializer {
    ...
    ..
    }
    
    build.gradle:
    
    buildscript {
        ext {
            springBootVersion = '1.3.5.RELEASE'
        }
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
            classpath("io.spring.gradle:dependency-management-plugin:0.5.6.RELEASE")
        }
    }
    ...
    ...
    
    dependencies {
        compile('io.springfox:springfox-swagger-ui:2.5.0')
        compile('io.springfox:springfox-swagger2:2.5.0')
        compile('org.springframework.cloud:spring-cloud-starter-feign')
    

    儿童模块

    package com.hitech.module.app;
    
    import com.hitech.module.base.BaseApplication;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
    import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
    import org.springframework.cloud.netflix.feign.EnableFeignClients;
    
    @SpringBootApplication(exclude = {MongoDataAutoConfiguration.class, MongoAutoConfiguration.class},
            scanBasePackages = {"com.hitech.module.base", "com.hitech.module.app", })
    @EnableFeignClients("com.hitech.module.app.clients")
    public class MyServiceApplication extends BaseApplication {
    
        private static final Logger LOG = LoggerFactory.getLogger(MyServiceApplication.class);
    
        public static void main(String[] args) {
    
            String s1 = "google";
    
            LOG.info ("=== Started Orchestration Service ===");
            SpringApplication.run(MyServiceApplication.class, args);
    
    
        }
    }
    

    bootstrap.yml

    feign:
      hystrix:
        enabled: false
    datasource:
      audit:
        mongodb:
          host: localhost
          port: 27019
          database: audit
    

相关问题