如何通过FEIGN客户端发送SOAP对象?

时间:2019-06-16 17:42:06

标签: java spring spring-boot soap feign

我正在尝试通过FEIGN客户端发送SOAP消息。问题在于,当我发送Java对象时,实际上发送的是XML格式的请求,而不是SOAP格式。

客户端的配置如下:

@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);

}

查看日志,我发现我确实在发送此邮件:

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

当我真的应该发送以下消息时:

<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>

欢迎任何帮助,谢谢!

2 个答案:

答案 0 :(得分:1)

它的作品,但我补充说:

  1. 创建 package-info.java 到 package addRequest/AddResponse
    @XmlSchema(
            namespace = "http://tempuri.org/",
            elementFormDefault = XmlNsForm.QUALIFIED,
            xmlns = {
                    @XmlNs(prefix = "xsd", namespaceURI = "http://tempuri.org/")
            }
    )
    package your.package.add;
    
    import javax.xml.bind.annotation.XmlNs;
    import javax.xml.bind.annotation.XmlNsForm;
    import javax.xml.bind.annotation.XmlSchema;

  1. 另外,你需要添加一个拦截器来设置 content-type 和 soapAction:
    import feign.RequestInterceptor;
    import feign.RequestTemplate;
    
    public class FeignRequestSoapInterceptor implements RequestInterceptor {
    
        @Override
        public void apply(RequestTemplate requestTemplate) {
            requestTemplate.header("Content-Type", "text/xml");
            requestTemplate.header("soapAction", "http://tempuri.org/Add");
        }
    }

  1. 在 MySoapClientConfiguration 中,添加 FeignRequestSoapInterceptor:
@Configuration
public class MySoapClientConfiguration {

    private static final JAXBContextFactory jaxbFactory = new JAXBContextFactory.Builder()
            .withMarshallerJAXBEncoding("UTF-8")
            .build();

    @Bean
    public Encoder feignEncoder() {
        return new SOAPEncoder(jaxbFactory);
    }

    @Bean
    public Decoder feignDecoder() {
        return new SOAPDecoder(jaxbFactory);
    }

    @Bean
    public FeignRequestSoapInterceptor feignRequestSoapInterceptor() {
        return new FeignRequestSoapInterceptor();
    }
}
  1. FeignClient:
    @FeignClient(
      name = "calculatorServer", 
      url = "http://www.dneonline.com/calculator.asmx"
      configuration = MySoapClientConfiguration.class)
    public interface AEMWebServiceFeignClient{
    
        @PostMapping("/Add")
        AddResponse calculate(@RequestBody Add addRequest);
    
    }

答案 1 :(得分:0)

您必须定义一个自定义的Feign编解码器以使用SOAP,如here中所述。

要将其与FeignClient集成,应为其定义一个自定义配置类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);
    }
}