question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Running @FeignClient with application/x-www-form-urlencoded throws IllegalStateException: Method has too many Body parameters

See original GitHub issue

Is it possible to use feign-form’s support for application/x-www-form-urlencoded forms with Spring Cloud’s @EnableFeignClients/@FeignClient setup?

Currently, I am getting the following exception when starting the ApplicationContext:

java.lang.IllegalStateException: Method has too many Body parameters: public abstract java.lang.String com.example.feigntest.MyClient.foo(java.lang.String,java.lang.String,java.lang.String)

To me, that is an indication that loading the feign-form support didn’t quite work.

I’m using org.springframework.cloud:spring-cloud-starter-openfeign, org.springframework.boot:spring-boot-starter and for dependencyManagement org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR3, all with a org.springframework.boot:spring-boot-starter-parent:2.1.9.RELEASE parent.

My setup, running against a simple standalone wiremock with --print-all-network-traffic flag and a single simple mock:

@EnableFeignClients
@SpringBootApplication
public class FeignTestApplication implements CommandLineRunner {
	@Autowired private MyApp myApp;
	public static void main(String[] args) { SpringApplication.run(FeignTestApplication.class, args); }
	@Override public void run(String... args) { myApp.run(); }
}

@Component
public class MyApp {
    @Autowired private MyClient myClient;
    public void run() { String result = myClient.foo("a", "b", "c"); }
}

@FeignClient(name="myClient", url = "http://localhost:8080", configuration = MyClientConfig.class)
public interface MyClient {
    @RequestMapping(method = RequestMethod.POST, value = "/foo")
    @Headers("Content-Type: application/x-www-form-urlencoded")
    public String foo(@Param("p1") String p1, @Param("p2") String p2, @Param("p3") String p3);
}

public class MyClientConfig { // NB: is @Configuration required here?
    @Autowired private ObjectFactory<HttpMessageConverters> messageConverters;
    @Bean public Encoder feignFormEncoder () { return new SpringFormEncoder(new SpringEncoder(messageConverters)); }
}

When I remove the Spring Cloud feign annotations (@EnableFeignClients, @FeignClient) and replace both the autowired myClient property in MyApp with private MyClient myClient = Feign.builder().encoder(new FormEncoder()).target(MyClient.class, "http://localhost:8080"); and the @RequestMapping annotation in MyClient with @RequestLine("POST /foo"), it all works.

So, I know I haven’t gone completely wrong. I’m basically just wondering if feign-forms support for application/x-www-form-urlencoded forms can be made to work with Spring Cloud’s @EnableFeignClients/@FeignClient magic (and I’ve made a mistake somewhere), or if the exception is to be expected?

Also (and probably somewhat unrelated), would I have to use the @Configuration annotation on the MyClientConfig class if I used the @FeignClient annotation and wanted to refine the config programatically?

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:3
  • Comments:7

github_iconTop GitHub Comments

4reactions
anno1985commented, Oct 17, 2019

NB: Looks like the following does the trick, without the @Headers annotation:

@RequestMapping(method = RequestMethod.POST, value = "/foo", consumes = "application/x-www-form-urlencoded")
public String foo(MyPojo payload);

with a wrapper whose properties match the params from before:

public class MyPojo {
    public MyPojo(String p1, String p2, String p3) {
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }
    public String p1, p2, p3;

Log:

2019-10-17 11:05:04.269 Incoming bytes: POST /foo HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept: */*
User-Agent: Java/1.8.0_212
Host: localhost:8080
Connection: keep-alive
Content-Length: 14


2019-10-17 11:05:04.270 Incoming bytes: p1=a&p2=b&p3=c

Oh, and btw: the @Configuration is not required.

1reaction
yandinizzupcommented, Apr 4, 2020

I tried to use following code, but I got the same error when I was using LinkedHasMap.

I tried to use FormEncoder Configuration, but when I try to do a normal request, in other Client he tries to encode my request without set configuration in Client properties.

@FeignClient(name = "Authentication", url = "\${url.sts}")
interface Authentication {
    @PostMapping(consumes = [MediaType.APPLICATION_FORM_URLENCODED_VALUE],
            value = ["/api/oauth/token"],
            produces = ["application/json"])
    fun auth(forms: Headers): Auth
}

Headers class:

class Headers() {

    @JsonProperty("grant_type")
    val grantType: String = GRANT_TYPE_STS
    @JsonProperty("x-flow-ID")
    val flowId = UUID.randomUUID().toString()
    @JsonProperty("x-correlationID")
    val correlationId = UUID.randomUUID().toString()
    @JsonProperty("client_id")
    var clientId: String = Strings.EMPTY
    @JsonProperty("client_secret")
    var clientSecret: String = Strings.EMPTY

    constructor(clientId: String, clientSecret: String): this(){
        this.clientId = clientId
        this.clientSecret = clientSecret
    }

    companion object {
        const val GRANT_TYPE_STS = "client_credentials"
    }
}

Produces class:

class Auth() {
    @JsonProperty("access_token")
    var accessToken: String = Strings.EMPTY

    @JsonProperty("token_type")
    var tokenType: String = Strings.EMPTY

    @JsonProperty("expires_in")
    var expiresIn: Int = 0

    @JsonProperty("refresh_token")
    var refreshToken: String = Strings.EMPTY

    var scope: String = Strings.EMPTY

    var active: Boolean = true
}

If someone knows any solution without use Encoder bean I’ll be thankfull

Read more comments on GitHub >

github_iconTop Results From Across the Web

SpringBoot FeignClient Method has too many paramters
If you have multiple arguments with one request body and more params. Specify the argument types using exact annotations:
Read more >
Method has too many Body parameters · Issue #793 ... - GitHub
Request method: @RequestMapping(method = RequestMethod. ... IllegalStateException: Method has too many Body parameters #793.
Read more >
Developers - Running @FeignClient with application/x-www ...
Running @FeignClient with application/x-www-form-urlencoded throws IllegalStateException: Method has too many Body parameters.
Read more >
OpenFeign/feign - Gitter
IllegalStateException : Method has too many Body parameters: public abstract rx.Observable com.picpay.api.consumer.client.ConsumerClient.
Read more >
Feign整合报错:java.lang.IllegalStateException: Method has ...
IllegalStateException : Method has too many Body parameters ... FeignClient; @FeignClient("app-mayikt-pay") public interface PayContextServiceFeign extends ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found