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