How to accept feign response in application/xml
Asked Answered
M

2

5

I am invoking 3rd party API which returns a response in XML format. As I have not created any POJO to hold response in my consumer service I am using java.lang.Object for same.

I am getting the below error.

org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class java.lang.Object] and content type [application/xml]
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:126) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.cloud.openfeign.support.SpringDecoder.decode(SpringDecoder.java:59) ~[spring-cloud-openfeign-core-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.cloud.openfeign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:62) ~[spring-cloud-openfeign-core-2.2.5.RELEASE.jar:2.2.5.RELEASE]

My feign client code

@FeignClient(value = "SERVICE", url = "https://goog.dummyservice/api1/v1", decode404 = true)
public interface UserFeign {

    @GetMapping(value = "/docs/{profile}/{protocol}", consumes = MediaType.APPLICATION_XML_VALUE)
    Object getUserData(@RequestHeader("Authorization") String token,
                         @PathVariable("profile") String profile,
                         @PathVariable("protocol") String protocol);
}

I wanted to know how to hold XML response through feign.

Malign answered 19/11, 2020 at 10:31 Comment(1)
were you able to figure this out?Bailey
C
4

FeignClientConfiguration.java

@Configuration
@RequiredArgsConstructor
public class FeignClientConfiguration {

private final ObjectFactory<HttpMessageConverters> messageConverters;

@Bean
public Encoder feignFormEncoder() {
    return new FormEncoder(new SpringEncoder(messageConverters));
}

/*@Bean
public Decoder feignDecoder() {
    MappingJackson2XmlHttpMessageConverter c = new MappingJackson2XmlHttpMessageConverter();
    ObjectFactory<HttpMessageConverters> objectFactory = () ->new HttpMessageConverters(c);
    return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}*/

}

ConsultaClient.java

    @FeignClient(url = "${api.serpro.url}",
            name = "name",
            configuration = FeignClientConfiguration.class)
    public interface ConsultaClient {

    @PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_XML_VALUE)
    @Headers("Content-Type: application/x-www-form-urlencoded")
    List<DocumentoDTO> getData(ParamsDTO params);
}
Capillaceous answered 17/12, 2021 at 20:45 Comment(0)
U
2

The steps sequence below helped me to solve this problem:

1 - Add the jackson-dataformat-xml dependence to your pom.xml

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.14.1</version>
</dependency>

2 - Add this customized Config in UserFeign.java

@FeignClient(value = "SERVICE", url = "https://goog.dummyservice/api1/v1", decode404 = true, configuration = UserFeign.Configuration.class)
public interface UserFeign {

@GetMapping(value = "/docs/{profile}/{protocol}", consumes = MediaType.APPLICATION_XML_VALUE)
Object getUserData(@RequestHeader("Authorization") String token,
                     @PathVariable("profile") String profile,
                     @PathVariable("protocol") String protocol);

class Configuration {
    @Bean
    public Decoder feignDecoder() {
        return (response, type) -> {
            String bodyStr = Util.toString(response.body().asReader(Util.UTF_8));
            JavaType javaType = TypeFactory.defaultInstance().constructType(type);
            return new XmlMapper().readValue(bodyStr, javaType);
        };
    }
}

}

Uncourtly answered 17/1, 2023 at 16:19 Comment(1)
Saved the day, thanks so much!Pompous

© 2022 - 2024 — McMap. All rights reserved.