SpringCloud使用Feign,以SOAP,XML方式调用接口
实现目标
<soapenv:Envelope xmlns:soapenv=“http://schemas.xmlsoap.org/soap/envelope/” xmlns:cov=“http://www.test.com/lmc/cov”>
添加自定义头部:xmlns:cov=“http://www.test.com/lmc/cov”
1.feign配置Encoder,实现SOAP支持自定义头部
import feign.codec.Decoder;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import feign.jaxb.JAXBContextFactory;
import feign.soap.SOAPDecoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.w3c.dom.Document;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.TransformerFactoryConfigurationError;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import static javax.xml.soap.SOAPConstants.DEFAULT_SOAP_PROTOCOL;
@Slf4j
public class CovFeignClientConfiguration {
private Charset charsetEncoding = StandardCharsets.UTF_8;
private String soapProtocol = DEFAULT_SOAP_PROTOCOL;
private static final JAXBContextFactory jaxbContextFactory = new JAXBContextFactory.Builder()
.withMarshallerJAXBEncoding("UTF-8")
.build();
@Bean
public Encoder feignEncoder() {
return (object, bodyType, template) -> {
if (!(bodyType instanceof Class)) {
throw new UnsupportedOperationException(
"SOAP only supports encoding raw types. Found " + bodyType);
}
try {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Marshaller marshaller = jaxbContextFactory.createMarshaller((Class<?>) bodyType);
marshaller.marshal(object, document);
SOAPMessage soapMessage = MessageFactory.newInstance(soapProtocol).createMessage();
SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
soapEnvelope.addNamespaceDeclaration("cov", "http://www.test.com/lmc/cov");
soapMessage.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, charsetEncoding.displayName());
soapMessage.getSOAPBody().addDocument(document);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
soapMessage.writeTo(bos);
template.body(new String(bos.toByteArray()).replaceAll("CovRequest", "cov:CovRequest"));
} catch (SOAPException | JAXBException | ParserConfigurationException | IOException | TransformerFactoryConfigurationError e) {
throw new EncodeException(e.toString(), e);
}
};
}
@Bean
public Decoder feignDecoder() {
return new SOAPDecoder(jaxbContextFactory);
}
}
2.使用地方通过‘configuration’引入即可
import com.lenovo.quotation.config.feign.CovFeignClientConfiguration;
import com.lenovo.quotation.service.dto.covrequest.CovFeignResult;
import com.lenovo.quotation.service.dto.covrequest.CovResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(name = "test", configuration = {CovFeignClientConfiguration.class}, url = "${test.host}")
@RequestMapping("/v1.0")
public interface TestFeignClient {
@PostMapping(value = "/test", consumes = { MediaType.TEXT_XML_VALUE }, produces = MediaType.TEXT_XML_VALUE)
TestFeignResult sendTestBody(TestResult testResult);
}
3.接口调用示例
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cov="http://www.test.com/lmc/cov">
<soapenv:Header/>
<soapenv:Body>
<cov:CovRequest source="test">
<BuildEntity Build="test">
</BuildEntity>
</cov:CovRequest>
</soapenv:Body>
</soapenv:Envelope>
4.对于SOAP里面的内容
参考:
javax.xml.bind.annotation包下用法:
@XmlRootElement
@XmlAttribute
@XmlElement