Search code examples
javaspringspring-bootsoapfeign

How to send a SOAP object with FEIGN client?


I'm trying to send a SOAP message via a FEIGN client. The problem is that when I send the java object, what is actually being sent is a request with an xml format, instead of a SOAP format.

The client is configured as follows:

@FeignClient(name = "calculatorServer", url = "http://www.dneonline.com/calculator.asmx")
public interface AEMWebServiceFeignClient{

    @PostMapping(value = "", consumes = MediaType.TEXT_XML, produces = MediaType.TEXT_XML)
    AddResponse calculate(@RequestBody Add addRequest);

}

Looking at the log I see that I am really sending this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Add xmlns="http://tempuri.org/">
    <intA>2</intA>
    <intB>0</intB>
</Add>

When I really should be sending the following message:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:Add>
         <tem:intA>2</tem:intA>
         <tem:intB>0</tem:intB>
      </tem:Add>
   </soapenv:Body>
</soapenv:Envelope>

Any help is welcome, thanks!


Solution

  • You must define a custom Feign codec to use SOAP, as described in here.

    To integrate it with FeignClient, you should define a custom configuration class for it, reference.

    @FeignClient(
      name = "calculatorServer", 
      url = "http://www.dneonline.com/calculator.asmx"
      configuration = MySoapClientConfiguration.class)
    public interface AEMWebServiceFeignClient{
    
        @PostMapping(value = "", consumes = MediaType.TEXT_XML, produces = MediaType.TEXT_XML)
        AddResponse calculate(@RequestBody Add addRequest);
    
    }
    
    @Configuration
    public class MySoapClientConfiguration {
    
        private static final JAXBContextFactory jaxbFactory = new JAXBContextFactory.Builder()
           .withMarshallerJAXBEncoding("UTF-8")
           .withMarshallerSchemaLocation("http://apihost http://apihost/schema.xsd")
           .build();
    
        @Bean
        public Encoder feignEncoder() {
            return new SOAPEncoder(jaxbFactory);
        }
        @Bean
        public Decoder feignDecoder() {
            return new SOAPDecoder(jaxbFactory);
        }
    }