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