Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Springcloud Netflix Feign Parameters order #1915

Closed
julianobrasil opened this issue May 4, 2017 · 9 comments
Closed

Springcloud Netflix Feign Parameters order #1915

julianobrasil opened this issue May 4, 2017 · 9 comments

Comments

@julianobrasil
Copy link

julianobrasil commented May 4, 2017

EDIT: In the description bellow, it's not a compilation error. The error occurs during the startup process.

Is there any reason that explains why I get a compilation error (Body parameters cannot be used with form parameters) when declare a feign interface method like this:

a) foo(@PathVariable("pathVariableName") String pathVariable, @RequestBody List<String> anyVariable)

but everything works fine when I use this (switching the parameters order):

b) foo(@RequestBody List<String> anyVariable, @PathVariable("pathVariableName") String pathVariable)

In the current project all other feign methods work just fine in the former form. I don't know if this information is important, but this is the only one in which I try to use a list annotated with @RequestBody parameter.

Does the order of the parameters matters here like this answer? In this case, in which situations should I pay attention to the parameters order? Feign documentation seems to use it the way I experienced the problem.

By the way: I haven't tried to run the application yet, so I don't know how this will behave at runtime.

@spencergibb
Copy link
Member

Order shouldn't matter.

@julianobrasil
Copy link
Author

julianobrasil commented May 4, 2017

And does the fact of the @requestbody annotates a List<> matter? Maybe it's just a coincidence, but this is also the only place where I have a @requestbody annotating a List<>. I put this question in stackoverflow and someone there think that there's a limitation in using @requestbody with @PathVariable. Since I saw nothing about this in documentation, I decided to bring this question to github.

@spencergibb
Copy link
Member

I don't think so. Also, is this really a 'compilation error'?

@julianobrasil
Copy link
Author

I'll check it again.

@julianobrasil
Copy link
Author

julianobrasil commented May 4, 2017

Actually is during the application startup (I fixed the question above, thanks):

2017-05-04 15:16:10.071 ERROR 22952 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'permissaoController': Unsatisfied dependency expressed through field 'permissaoService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'permissaoServiceImpl': Unsatisfied dependency expressed through field 'permissaoFeign'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'br.alfa.tutoria.core.feign.authService.PermissaoFeign': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Body parameters cannot be used with form parameters.
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
	at br.alfa.tutoria.AlfaTutoriaApplication.main(AlfaTutoriaApplication.java:33) [classes/:na]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'permissaoServiceImpl': Unsatisfied dependency expressed through field 'permissaoFeign'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'br.alfa.tutoria.core.feign.authService.PermissaoFeign': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Body parameters cannot be used with form parameters.
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	... 19 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'br.alfa.tutoria.core.feign.authService.PermissaoFeign': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Body parameters cannot be used with form parameters.
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:175) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1634) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1309) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1275) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1101) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	... 32 common frames omitted
Caused by: java.lang.IllegalStateException: Body parameters cannot be used with form parameters.
	at feign.Util.checkState(Util.java:128) ~[feign-core-9.3.1.jar:na]
	at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:112) ~[feign-core-9.3.1.jar:na]
	at org.springframework.cloud.netflix.feign.support.SpringMvcContract.parseAndValidateMetadata(SpringMvcContract.java:133) ~[spring-cloud-netflix-core-1.2.6.RELEASE.jar:1.2.6.RELEASE]
	at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:64) ~[feign-core-9.3.1.jar:na]
	at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:146) ~[feign-core-9.3.1.jar:na]
	at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:53) ~[feign-core-9.3.1.jar:na]
	at feign.Feign$Builder.target(Feign.java:209) ~[feign-core-9.3.1.jar:na]
	at org.springframework.cloud.netflix.feign.HystrixTargeter.target(HystrixTargeter.java:36) ~[spring-cloud-netflix-core-1.2.6.RELEASE.jar:1.2.6.RELEASE]
	at org.springframework.cloud.netflix.feign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:184) ~[spring-cloud-netflix-core-1.2.6.RELEASE.jar:1.2.6.RELEASE]
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	... 42 common frames omitted

@spencergibb
Copy link
Member

That's what I thought. I wonder why it thinks you have form parameters? What does the whole feign client look like?

@julianobrasil
Copy link
Author

@RequestMapping(value = "/permissions/by-name/{appID}", method = RequestMethod.POST)
List<Permission> findByNameIn(@PathVariable("appID") String appID, 
                              @RequestBody List<String> permissionNames);

@julianobrasil
Copy link
Author

Ashamed of myself. I mistyped appID in @PathVariable. I had typed "appId". Sorry for taking your time because of this silly mistake.

@tonyfarney
Copy link

In my case this is not working:

@RequestMapping(
        value = "/api/admin/risk-analysis/{riskAnalysisId:[0-9]+}/biometrics/send", method = RequestMethod.POST,
        consumes = MediaType.APPLICATION_JSON_VALUE
    )
    void sendRiskAnalysisBiolink(
        @PathVariable("riskAnalysisId") Long riskAnalysisId,
        @Valid @RequestBody SendRiskAnalysisBiometricsRequest req
    );

But when I remove the REGEX it got working:

@RequestMapping(
        value = "/api/admin/risk-analysis/{riskAnalysisId}/biometrics/send", method = RequestMethod.POST,
        consumes = MediaType.APPLICATION_JSON_VALUE
    )
    void sendRiskAnalysisBiolink(
        @PathVariable("riskAnalysisId") Long riskAnalysisId,
        @Valid @RequestBody SendRiskAnalysisBiometricsRequest req
    );

Is this a bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants