1、例如一个对象:

{
    "Label3":"111",
    "Label4":["4441","4442"],
    "Label5":[{"Label5_1":"5551","Label5_2":"5552"},{"Label5_1":"5553","Label5_2":"5554"}]
}

2、对应SOAP协议XML报文

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope">
    <soapenv:Header/>
    <soapenv:Body>
        <Label1 xmlns="http://xxx.xxxx.com/xxx/xxx">
            <Label2>
                <Label3>111</Label3>
                <array>
                    <Label4>4441</Label4>
                    <Label4>4442</Label4>
                </array>
                <array>
                    <Label5>
                        <Label5_1>5551</Label5_1>
                        <Label5_2>5552</Label5_2>
                    </Label5>
                    <Label5>
                        <Label5_1>5553</Label5_1>
                        <Label5_2>5554</Label5_2>
                    </Label5>
                </array>
            </Label2>
        </Label1>
    </soapenv:Body>
</soapenv:Envelope>

3、可能用到的依赖包

<!--json和xml互转所需要的依赖-->
<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.0.0</version>
</dependency>
<dependency>
    <groupId>de.odysseus.staxon</groupId>
    <artifactId>staxon</artifactId>
    <version>1.3</version>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.1</version>
</dependency>    

4、JSON转SOAP协议XML报文工具类

本文主要通过SOAPMessage对象类进行JSON和SOAP协议XML之间进行转换,先把对象转成JSON字符串,再调用工具类方法,其中细节根据自己业务进行修改。

import com.alibaba.fastjson.JSON;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.lang.StringUtils;


import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.*;

public class JsonToSOAPXmlUtil {


    private static final String Label1 = "Label1";

    private static final String LABEL1_URL = "http://xxx.xxxx.com/xxx/xxx";
    
    private static final String Label2 = "Label2";
    
    private static final String PREFERRED_PREFIX = "soapenv";

    private static final String ARRAY_ELEMENT = "array";
    

    /**
     * 获取SOAP协议XML字符串
     *
     * @param json json字符串
     * @return SOAP协议xml报文
     * @throws SOAPException
     * @throws IOException
     */
    public static String getSoapXml(String json)
            throws SOAPException, IOException {
        if(org.apache.commons.lang3.StringUtils.isBlank(json)){
            json = JSON.toJSONString(new HashMap<>());
        }
        //SOAPConstants.SOAP_1_1_PROTOCOL对应报文<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope"><SOAP-ENV:Header><SOAP-ENV:Body>
        MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
        SOAPMessage message = messageFactory.createMessage();
        //设置编码
        message.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8");
        SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();

        // 根据WSDL组装soap xml
        //先移除原先的命名空间描述的前缀SOAP-ENV,根据自己业务决定是否需要
        envelope.removeNamespaceDeclaration(envelope.getPrefix());
        //重新设置前缀为soapenv,则报文为<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope">
        envelope.setPrefix(this.PREFERRED_PREFIX);
        SOAPHeader header = message.getSOAPHeader();
        //设置Header的前缀为soapenv,对应报文<soapenv:Header>
        header.setPrefix(this.PREFERRED_PREFIX);
        SOAPBody body = message.getSOAPBody();
        //设置Body的前缀为soapenv,对应报文<soapenv:Body>
        body.setPrefix(this.PREFERRED_PREFIX);
        // SOAPBody body = envelope.getBody();
        //设置一个父级标签LABEL1和命名空间,对应报文为<Label1 xmlns="http://xxx.xxxx.com/xxx/xxx">
        QName qName = new QName(this.LABEL1_URL, this.LABEL1, "");
        SOAPElement childElement = body.addChildElement(qName);

        //LABEL1添加子标签LABEL2
        SOAPElement childElement1 = childElement.addChildElement(this.Label2);
        //调用方法jsonToSOAPElement,json参数转成XML格式作为LABEL2的子标签
        jsonToSOAPElement(json, childElement1);

        message.writeTo(System.out);
        return SOAPMessageToXmlString(message);
    }
    
    /**
     * SOAPMessage对象转xml格式的字符串
     *
     * @param soapMessage soapMessage对象
     * @return xml格式的字符串
     * @throws SOAPException
     * @throws TransformerException
     */
    public static String SOAPMessageToXmlString(SOAPMessage soapMessage) throws SOAPException, TransformerException {
        org.w3c.dom.Document ownerDocument = soapMessage.getSOAPPart().getEnvelope().getOwnerDocument();
        StringWriter stringWriter = new StringWriter();
        TransformerFactory.newInstance().newTransformer().transform(new DOMSource(ownerDocument),
                new StreamResult(stringWriter));
        return stringWriter.toString();
    }
    
    /**
     * 将json字符串转成xml
     *
     * @param json          json字符串
     * @param parentElement xml根节点
     * @return
     */
    private static void jsonToSOAPElement(String json, SOAPElement parentElement) throws SOAPException {
        JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
        addSonElement(jsonObject, parentElement, null);
    }
    
    /**
     * 将json字符串转成SOAPElement
     * 递归处理JSON字符串
     * @param jsonElement   待解析json对象元素
     * @param parentElement 上一层xml的dom对象
     * @param name          父标签名称
     * @return
     */
    private static void addSonElement(JsonElement jsonElement, SOAPElement parentElement, String name)
            throws SOAPException {
        if (jsonElement instanceof JsonArray) {
            // 如果是集合,需要在外面包一层<array></array>标签
            SOAPElement arrayParentElement = parentElement.addChildElement(this.ARRAY_ELEMENT);
            JsonArray sonJsonArray = (JsonArray) jsonElement;
            for (int i = 0; i < sonJsonArray.size(); i++) {
                JsonElement arrayElement = sonJsonArray.get(i);
                addSonElement(arrayElement, arrayParentElement, name);
            }
        } else if (jsonElement instanceof JsonObject) {
            JsonObject sonJsonObject = (JsonObject) jsonElement;
            SOAPElement currentElement = null;
            if (name != null) {
                currentElement = parentElement.addChildElement(name);
            }
            Set<Map.Entry<String, JsonElement>> set = sonJsonObject.entrySet();
            for (Map.Entry<String, JsonElement> s : set) {
                addSonElement(s.getValue(), currentElement != null ? currentElement : parentElement, s.getKey());
            }
        } else {
            if (jsonElement.isJsonNull()) {
                addElementAttribute(parentElement, name, null);
            } else {
                addElementAttribute(parentElement, name, jsonElement.getAsString());
            }
        }
    }
    
    /**为标签设置值
     * @param element 父亲节点
     * @param name    子节点名字
     * @param value   子节点值
     */
    public static void addElementAttribute(SOAPElement element, String name, String value) throws SOAPException {
        SOAPElement element1 = element.addChildElement(name);
        if (StringUtils.isNotBlank(value)) {
            element1.setValue(value);
        }
    }
    
}

 

5、SOAP协议XML字符串转Map

下面是方法,

(1)先调用formartSoapString(String soapString)把SOAP协议XML字符串转成SOAPMessage对象

(2)然后调用SOAPMessageToMap(SOAPMessage soapMessage),把SOAPMessage对象转成Map

    
    
    
    /**
     * SOAP协议xml报文字符串 转 SOAPMessage对象
     *
     * @param soapString xml报文字符串
     * @return SOAPMessage对象
     */
    public static SOAPMessage SoapXMLStringToSOAPMessage(String soapString) {
        MessageFactory messageFactory;
        try {
            messageFactory = MessageFactory.newInstance();
            SOAPMessage reqmsg = messageFactory.createMessage(new MimeHeaders(),
                    new ByteArrayInputStream(soapString.getBytes(Charset.forName("UTF-8"))));
            reqmsg.saveChanges();
            return reqmsg;
        } catch (Exception e) {
            throw new IllegalArgumentException(ErrorCodeEnum.XML_ERROR.getCode());
        }
    }
    
    /**
     * soapMessage对象 转 map
     *
     * @param soapMessage soapMessage对象
     * @return map
     * @throws SOAPException
     * @throws TransformerException
     * @throws DocumentException
     */
    public static Map<String, Object> SOAPMessageToMap(SOAPMessage soapMessage)
            throws SOAPException, TransformerException, DocumentException {
        org.w3c.dom.Document document = soapMessage.getSOAPPart().getEnvelope().getOwnerDocument();
        StringWriter writer = new StringWriter();
        TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(writer));
        Element rootElement = DocumentHelper.parseText(writer.toString()).getRootElement();
        //调用parseXmlToMap方法处理Element
        Map<String, Object> map = parseElementToMap(rootElement);
        return map;
    }
    
    /**
     * Element转Map
     *
     * @param rootElement 根元素Element
     * @return
     */
    public static Map<String, Object> parseElementToMap(Element rootElement) {
        Map<String, Object> resultMap = new HashMap<>();
        //如果标签是<array>,ARRAY_ELEMENT = "array"
        if (ARRAY_ELEMENT.equals(rootElement.getName())) {
            ArrayList<Object> objectArrayList = parseList(rootElement);
            if(objectArrayList.size()>0){
                //如果array标签有子标签,则拿第一个子标签的名字作为集合名字
                resultMap.put(rootElement.elements().get(0).getName(), objectArrayList);
            }
        } else {
            Map<String, Object> sonObjectMap = parseObject(rootElement);
            resultMap.put(rootElement.getName(), sonObjectMap);
        }
        return resultMap;
    }

    /**
     * 获取对象map
     *
     * @param parentElement 父节点Element
     * @return
     */
    public static Map<String, Object> parseObject(Element parentElement) {
        Map<String, Object> resultMap = new HashMap<>();
        List<Element> elements = parentElement.elements();
        if (elements != null) {
            for (Element el : elements) {
                String elName = el.getName();
                //如果标签是<array>,ARRAY_ELEMENT = "array"
                if (ARRAY_ELEMENT.equals(elName)) {
                    ArrayList<Object> elList = parseList(el);
                    resultMap.put(el.elements().get(0).getName(), elList);
                } else {
                    if (el.elements().size() > 0) {
                        Map<String, Object> objectMap = parseObject(el);
                        resultMap.put(el.getName(), objectMap);
                    } else {
                        resultMap.put(el.getName(), el.getTextTrim());
                    }
                }
            }
        }

        return resultMap;
    }

    /**
     * 获取集合
     *
     * @param arrayElement Array标签Element
     * @return Array标签里的数据集合
     */
    public static ArrayList<Object> parseList(Element arrayElement) {
        ArrayList<Object> list = new ArrayList<>();
        //如果标签是<array>,ARRAY_ELEMENT = "array"
        if (ARRAY_ELEMENT.equals(arrayElement.getName())) {
            List<Element> elements = arrayElement.elements();
            if (elements != null) {
                for (Element el : elements) {
                    if (el.elements().size() > 0) {
                        Map<String, Object> map = parseObject(el);
                        list.add(map);
                    } else {
                        list.add(el.getTextTrim());
                    }
                }
            }
        }
        return list;
    }