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

posted @ 2019-11-23 20:48  叶落无蝉鸣  阅读(727)  评论(0编辑  收藏  举报