如何使用 FEIGN 客户端发送 SOAP 对象?
How to send a SOAP object with FEIGN client?
我正在尝试通过 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>
欢迎任何帮助,谢谢!
您必须定义自定义 Feign 编解码器才能使用 SOAP,如 here 中所述。
要将它与FeignClient集成,你应该为它定义一个自定义配置class,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);
}
}
有效,但我添加了:
- 创建包-info.java 到包 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;
- 此外,您需要添加一个拦截器来设置内容类型和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");
}
}
- 在 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();
}
}
- FeignClient:
@FeignClient(
name = "calculatorServer",
url = "http://www.dneonline.com/calculator.asmx"
configuration = MySoapClientConfiguration.class)
public interface AEMWebServiceFeignClient{
@PostMapping("/Add")
AddResponse calculate(@RequestBody Add addRequest);
}
我正在尝试通过 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>
欢迎任何帮助,谢谢!
您必须定义自定义 Feign 编解码器才能使用 SOAP,如 here 中所述。
要将它与FeignClient集成,你应该为它定义一个自定义配置class,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);
}
}
有效,但我添加了:
- 创建包-info.java 到包 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;
- 此外,您需要添加一个拦截器来设置内容类型和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");
}
}
- 在 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();
}
}
- FeignClient:
@FeignClient(
name = "calculatorServer",
url = "http://www.dneonline.com/calculator.asmx"
configuration = MySoapClientConfiguration.class)
public interface AEMWebServiceFeignClient{
@PostMapping("/Add")
AddResponse calculate(@RequestBody Add addRequest);
}