rest - Can't get Feign Client to work for a basic example -


can't feign client work. first tried post. kept running errors related encoder/decoder saying type not right. found example on github call simple api , decided give shot. still fails

on github , online, seeing multiple versions of feign client spring-cloud, openfeign, netflix.feign having different versions. describe what's best , stable feign client 1 should use production?

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;    .. stuff       @requestmapping(value="/postsomething",method = requestmethod.post)     @apioperation(value = "configures something",             notes = "basic rest controller testing feign")      public responseentity<someresponse> feignpost(             uricomponentsbuilder builder,             @apiparam(name = "myrequest",              value = "request configuring something",              required = true)             @valid @requestbody somerequest somerequest) {          string resp = null;         try {             resp = getfeignclient.posts();         } catch (exception er) {             er.printstacktrace();         }      } } 

application:

tried possible permutations of annotations thinking resolve autowire stuff still fails

@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 application startup failed

org.springframework.beans.factory.beancreationexception: error creating bean name 'testwlccontroller': injection of autowired dependencies failed; nested exception org.springframework.beans.factory.beancreationexception: not autowire field: private com.paa.controllers.getfeignclient com.paa.controllers.testwlccontroller.gfclient; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'com.aa..controllers.getfeignclient': factorybean threw exception on object creation; nested exception java.lang.nullpointerexception @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor.postprocesspropertyvalues(autowiredannotationbeanpostprocessor.java:334) ~[spring-beans-4.2.6.release.jar:4.2.6.release] @ 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.factory.support.defaultsingletonbeanregistry.getsingleton(defaultsingletonbeanregistry.java:230) ~[spring-beans-4.2.6.release.jar:4.2.6.release] @ org.springframework.beans.factory.support.abstractbeanfactory.dogetbean(abstractbeanfactory.java:302) ~[spring-beans-4.2.6.release.jar:4.2.6.release] @ org.springframework.beans.factory.support.abstractbeanfactory.getbean(abstractbeanfactory.java:197) ~[spring-beans-4.2.6.release.jar:4.2.6.release] @ org.springframework.beans.factory.support.defaultlistablebeanfactory.preinstantiatesingletons(defaultlistablebeanfactory.java:772) ~[spring-beans-4.2.6.release.jar:4.2.6.release] @ org.springframework.context.support.abstractapplicationcontext.finishbeanfactoryinitialization(abstractapplicationcontext.java:839) ~[spring-context-4.2.6.release.jar:4.2.6.release] @ org.springframework.context.support.abstractapplicationcontext.refresh(abstractapplicationcontext.java:538) ~[spring-context-4.2.6.release.jar:4.2.6.release] @ org.springframework.boot.context.embedded.embeddedwebapplicationcontext.refresh(embeddedwebapplicationcontext.java:118) ~[spring-boot-1.3.5.release.jar:1.3.5.release] @ org.springframework.boot.springapplication.refresh(springapplication.java:766) [spring-boot-1.3.5.release.jar:1.3.5.release] @ org.springframework.boot.springapplication.createandrefreshcontext(springapplication.java:361) [spring-boot-1.3.5.release.jar:1.3.5.release] @ org.springframework.boot.springapplication.run(springapplication.java:307) [spring-boot-1.3.5.release.jar:1.3.5.release] @ org.springframework.boot.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] @ com.paa.serviceapplication.main(serviceapplication.java:44) [bin/:na] caused by: org.springframework.beans.factory.beancreationexception: not autowire field: private com.paa.controllers.getfeignclient com.paa.controllers.testwlccontroller.gfclient; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'com.paa.controllers.getfeignclient': factorybean threw exception on object creation; nested exception java.lang.nullpointerexception @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor$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 frames omitted

i'm not sure if figured out yourself, sake of others might stumble across thread, below working example of trying do. i'll first point out few things incorrect, or @ least, not desired in code, show code works.

  1. you should try not use url attribute. instead, set list of servers using <feign client name>.ribbon.listofservers in bootstrap.yml (or bootstrap.properties). allows client side load balancing because listofservers can comma-separated list.
  2. using ribbon https connections, need specify 2 things don't need http connections. port, part of listofservers , <feign client name>.ribbon.issecure: true. without port, connection made port 80 , without issecure, http used.
  3. testing using curl, found reddit takes very long time respond. see post details of how break down total time taken request-response cycle.

    $ 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 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 

according netflix wiki, default read , connect timeouts 3000 milliseconds, timeout unless change those.

  1. you may have noticed specified user-agent header in curl request. that's because reddis seems picky , if not specified, returns http 429 "too many requests" of times. don't return retry-after header in response there's no telling how long need wait before making request.
  2. spring cloud netflix netflix feign open source, (a lot of) patience , debugging skills come handy.

"talk cheap. show me code." (torvalds, linus (2000-08-25)).

i generated gradle app using excellent spring initializr site. here's snippet build.gradle file.

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

Comments