0

This is my feign endpoint

@PostMapping(value = "url", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
MpcsAuthResponse obtainAccessToken(@RequestBody MpcsTokenRequest request);

and when I enable feign full logs I see that the body is empty

c.k.c.t.m.m.client.mpcs.MpcsClient -- [MpcsClient#obtainAccessToken] ---> POST <url> HTTP/1.1
11:16:47.532 [main] DEBUG c.k.c.t.m.m.client.mpcs.MpcsClient -- [MpcsClient#obtainAccessToken] Content-Type: application/x-www-form-urlencoded; charset=UTF-8
11:16:47.532 [main] DEBUG c.k.c.t.m.m.client.mpcs.MpcsClient -- [MpcsClient#obtainAccessToken] 
11:16:47.532 [main] DEBUG c.k.c.t.m.m.client.mpcs.MpcsClient -- [MpcsClient#obtainAccessToken] 
11:16:47.532 [main] DEBUG c.k.c.t.m.m.client.mpcs.MpcsClient -- [MpcsClient#obtainAccessToken] ---> END HTTP (0-byte body)

I have other feign clients that are working fine. The only time this happens is when I use APPLICATION_FORM_URLENCODED_VALUE.

I am on Java 17, spring boot 3.1.0 and fiegn comes from

org.springframework.cloud:spring-cloud-starter-openfeign:4.0.3

NOTE: If I use just String instead of the MpcsTokenRequest dto it works, so it is probably something with the encoders, but I can't figure it out

EDIT: this is how my DTO looks like

public record MpcsTokenRequest(@FormProperty("client_id")
                               String clientId,
                               @FormProperty("client_secret")
                               String clientSecret,
                               @FormProperty("grant_type")
                               String grantType) {
}

My client configuration

public class MpcsClientConfiguration {

    @Bean
    Encoder formEncoder() {
        return new feign.form.FormEncoder();
    }

    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

The problem was that feign doesn't serialize the form if its a record. https://github.com/OpenFeign/feign-form/issues/105

Converting my DTO to POJO solved it.

Borislav Stoilov
  • 3,247
  • 2
  • 21
  • 46

1 Answers1

0

you can try @SpringQueryMap:

@PostMapping(value = "url", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
MpcsAuthResponse obtainAccessToken(@SpringQueryMap MpcsTokenRequest request);

but make sure to add consumes = MediaType.MULTIPART_FORM_DATA_VALUE at the resource you want to consume : @PostMapping(value = "/url",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)