一.发送自定义soap报文(内嵌jsonString)获取返回报文工具类
import javax.xml.soap.*;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;
/**
* 发送自定义soap报文(内嵌jsonString)获取返回报文工具类
*/
public class SoapUtil {
//对接服务地址
private String addressUrl="http://XXXXXXXX";
public SoapHepler(String addressUrl) {
if(addressUrl!=null&&!"".equals(addressUrl.trim())){
this.addressUrl = addressUrl;
}
}
/**
* 添加所需信息
* @param bodyJsonStr 请求体json
* @param svcname 服务名称
* @param svccode 服务编码
* @param svcver 服务版本
* @param orisys 来源系统标识
* @param trantime 交易发起时间
* @param tranno 全局交易流水号
* @param branchno 操作员机构代码op
* @param userid 用户IDop
* @param tokenid 口令或令牌op
* @param signature 数字签名op
* @param branchnoo 机构代码
* @param destsys 目标系统标识
* @return
*/
public String sendSoapXml(String bodyJsonStr,
String svcname, String svccode,
String svcver,String orisys,
String trantime,String tranno,
String branchno,String userid,
String tokenid,String signature,
String branchnoo,String destsys) {
String AUTH_PREFIX = "cl";
String AUTH_NS = "http://www.e-chinalife.com/soa/";
String XSD_NS = "http://www.w3.org/2001/XMLSchema";
String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
try {
//实例化一个soap连接对象工厂
SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
//实例化一个连接对象
SOAPConnection connection = soapConnFactory.createConnection();
//实例化一个消息对象
MessageFactory messageFactory = MessageFactory.newInstance();
//实例化一个消息
SOAPMessage message = messageFactory.createMessage();
//获取消息中soap消息部分的句柄
SOAPPart soapPart = message.getSOAPPart();
//获取soap消息部分中的信封句柄
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.setPrefix("soapenv");
envelope.removeNamespaceDeclaration("SOAP-ENV");
// envelope.setAttribute("xmlns:xsd", XSD_NS);
//// envelope.setAttribute("xmlns:xsi", XSI_NS);
envelope.setAttribute("xmlns:soa", AUTH_NS);
//获取信封中需要填写的请求报文部分的句柄
//创建soap工厂
SOAPFactory soapFactory = SOAPFactory.newInstance();
//添加消息体以及json字符串
SOAPBody body = envelope.getBody();
body.setPrefix("soapenv");
SOAPBodyElement bodyElement = body.addBodyElement(envelope.createName("execute", "soa", null));
SOAPElement requestData = bodyElement.addChildElement("requestData","soa");
requestData.addTextNode(judgeNull(bodyJsonStr));
//添加信息头内容
SOAPHeader header = envelope.getHeader();
header.setPrefix("soapenv");
SOAPElement wsHeaderElm = soapFactory.createElement("HEADER", AUTH_PREFIX, AUTH_NS);
SOAPElement svcnameElm = soapFactory.createElement("SVCNAME");
SOAPElement svccodeNameElm = soapFactory.createElement("SVCCODE");
SOAPElement svcverElm = soapFactory.createElement("SVCVER");
SOAPElement orisysElm = soapFactory.createElement("ORISYS");
SOAPElement trantimeElm = soapFactory.createElement("TRANTIME");
SOAPElement trannoElm = soapFactory.createElement("TRANNO");
SOAPElement authElm = soapFactory.createElement("AUTH");
SOAPElement securityElm = soapFactory.createElement("SECURITY");
SOAPElement routeElm = soapFactory.createElement("ROUTE");
SOAPElement branchnoElm = soapFactory.createElement("BRANCHNO");
SOAPElement useridElm = soapFactory.createElement("USERID");
SOAPElement tokenidElm = soapFactory.createElement("TOKENID");
SOAPElement signatureElm = soapFactory.createElement("SIGNATURE");
SOAPElement branchnooElm = soapFactory.createElement("BRANCHNO");
SOAPElement destsysElm = soapFactory.createElement("DESTSYS");
//为上述消息头标签添加节点文本值
svcnameElm.addTextNode(judgeNull(svcname));
svccodeNameElm.addTextNode(judgeNull(svccode));
svcverElm.addTextNode(judgeNull(svcver));
orisysElm.addTextNode(judgeNull(orisys));
trantimeElm.addTextNode(judgeNull(trantime));
trannoElm.addTextNode(judgeNull(tranno));
branchnoElm.addTextNode(judgeNull(branchno));
useridElm.addTextNode(judgeNull(userid));
tokenidElm.addTextNode(judgeNull(tokenid));
signatureElm.addTextNode(judgeNull(signature));
branchnooElm.addTextNode(judgeNull(branchnoo));
destsysElm.addTextNode(judgeNull(destsys));
authElm.addChildElement(branchnoElm);
authElm.addChildElement(useridElm);
authElm.addChildElement(tokenidElm);
securityElm.addChildElement(signatureElm);
routeElm.addChildElement(branchnooElm);
routeElm.addChildElement(destsysElm);
wsHeaderElm.addChildElement(svcnameElm);
wsHeaderElm.addChildElement(svccodeNameElm);
wsHeaderElm.addChildElement(svcverElm);
wsHeaderElm.addChildElement(orisysElm);
wsHeaderElm.addChildElement(trantimeElm);
wsHeaderElm.addChildElement(trannoElm);
wsHeaderElm.addChildElement(authElm);
wsHeaderElm.addChildElement(securityElm);
wsHeaderElm.addChildElement(routeElm);
header.addChildElement(wsHeaderElm);
message.saveChanges();
System.out.println("输出报文,如下:");
message.writeTo(System.out);
//发送信息
SOAPMessage call = connection.call(message, addressUrl);
TransformerFactory transformerFactory=TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Source sourceContent = call.getSOAPPart().getContent();
StreamResult result = new StreamResult(new ByteArrayOutputStream());
transformer.transform(sourceContent,result);
//获取返回报文
String s = ((ByteArrayOutputStream) result.getOutputStream()).toString();
System.out.println("返回报文,如下:");
System.out.print( s);
connection.close();
return s;
} catch (Exception e) {
throw new BusinessException("返回报文失败 ,错误信息:"+e);
}
}
/**添加上述节点文本是不能为null
* 如果str为null 置为“”
* @param str
* @return
*/
public static String judgeNull(String str){
return (str==null)?"":str;
}
}
二. 解析返回soap报文,获取目标节点值
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 解析返回soap报文,获取目标节点值
*/
public class XMLUtil {
/**
* 将字符串类型的XML 转化成Docunent文档结构</p>
* @param parseStrXml 待转换的xml 字符串
* @return
*/
public static Document strXmlToDocument(String parseStrXml){
StringReader read = new StringReader(parseStrXml);
//创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
InputSource source = new InputSource(read);
//创建一个新的SAXBuilder
SAXBuilder sb = new SAXBuilder(); // 新建立构造器
Document doc = null;
try {
doc = sb.build(source);
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return doc;
}
/**
* 根据目标节点名获取值
* @param doc 文档结构
* @param finalNodeName 最终节点名
* @return
*/
public static String getValueByElementName(Document doc,String finalNodeName){
Element root = doc.getRootElement();
HashMap<String,Object> map=new HashMap<String,Object>();
//调用getChildAllText方法。获取目标子节点的值
Map<String,Object> resultmap=getChildAllText(doc, root,map);
String result=(String)resultmap.get(finalNodeName);
return result;
}
/**
* 递归获得子节点的值
* @param doc 文档结构
* @param e 节点元素
* @param resultmap 递归将值压入map中
* @return
*/
public static Map<String ,Object> getChildAllText(Document doc, Element e,HashMap<String,Object> resultmap)
{
if (e != null)
{
if (e.getChildren() != null) //如果存在子节点
{
List<Element> list = e.getChildren();
for (Element el : list) //循环输出
{
if(el.getChildren().size() > 0) //如果子节点还存在子节点,则递归获取
{
getChildAllText(doc, el,resultmap);
}
else
{
resultmap.put(el.getName(), el.getTextTrim()); //将叶子节点值压入map
}
}
}
}
return resultmap;
}
}
三.测试controller
import com.menno.insurance.chinalifeinsurance.utils.SoapHepler;
import com.menno.insurance.chinalifeinsurance.utils.XMLUtil;
import org.apache.axis.AxisFault;
import org.jdom.Document;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* just for test by fangyi
*/
@RestController
public class ControllerForTest {
@RequestMapping("/testSoap1")
public String getSoapXml() throws AxisFault {
String hospitalRegistrationUrl="http://218.107.129.186:8003/SOA/CIS/ApplyMDExchange";
Date date = new Date();
SimpleDateFormat ad= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
String format = ad.format(date);
//发送soap报文
SoapHepler soapHepler=new SoapHepler(hospitalRegistrationUrl);
String s = soapHepler.sendSoapXml(registrationData, "ApplyMDExchange", "CIS-0007",
"1.0", "SZSB-EPS", ""+format, "6", null, null, null,null, "000000", "CIS");
//解析,获取返回json
Document document = XMLUtil.strXmlToDocument(s);
String returnJson = XMLUtil.getValueByElementName(document, "return");
System.out.print(returnJson);
return returnJson;
}
}
四.效果
输出报文,如下:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soa="http://www.e-chinalife.com/soa/"><soapenv:Header><cl:HEADER xmlns:cl="http://www.e-chinalife.com/soa/"><SVCNAME>ApplyMDExchange</SVCNAME><SVCCODE>CIS-0007</SVCCODE><SVCVER>1.0</SVCVER><ORISYS>SZSB-EPS</ORISYS><TRANTIME>2018-02-22 16:50:38,101</TRANTIME><TRANNO>6</TRANNO><AUTH><BRANCHNO/><USERID/><TOKENID/></AUTH><SECURITY><SIGNATURE/></SECURITY><ROUTE><BRANCHNO>000000</BRANCHNO><DESTSYS>CIS</DESTSYS></ROUTE></cl:HEADER></soapenv:Header><soapenv:Body><soa:execute><soa:requestData xmlns:soa="http://www.e-chinalife.com/soa/"> { 'root': { 'head': { 'BusinessType': '3', 'CorrelationId': '172b9e03490c1143aa123f8f3096622074d0505e','MessageDateTime': '2016-9-26 13:53:05.12', 'MessageId': '201611210001', 'ReceiverAddress': '', 'ReceiverCode': 'UNCL', 'ReceiverName': '中国人寿保险股份有限公司(宜昌)', 'SenderAddress': '', 'SenderCode': '20161104001', 'SenderName': '天津社保局', 'StandardVersionCode': '1.0.0', 'TotalRecord': '', 'TransRefGUID': '201611210001', 'TransactionCode': 'S107', 'TransactionSubCode': '00' },'body': {'HospitalRegistration': { 'PersonGUID': '372922731004503', 'MedicalGUID': '201802010002', 'Name': '测试', 'GenderCode': '1', 'Birthday': '1973-10-03 00:00:00', 'CredentialNum': '372922731004503', 'CredentialType': 'I', 'InstituteCode': '120000', 'BelongInstituteAreaCode': '120000', 'AccidentDate': '', 'AccidentProcedure': '', 'AccidentReason': '2', 'Address': '武汉市青山区红卫路49街坊100门1号', 'AllergyHistory': '', 'BabyName': '', 'BedNumber': '44', 'BodyMassIndex': '', 'ChestCircumference': '', 'Company': '无', 'ComplicationCode': '', 'DiastolicPressure': '', 'FamilyDiseaseHistory': '', 'HeartRate': '', 'Height': '', 'HospitalNumber': '201674903', 'MainDiagnosisCode': 'J98.414', 'MainDiagnosisName': '肺部感染', 'MarriageStatus': '', 'MasterDoctor': '汤镇', 'MedicalDate': '2011-08-31 01:03:59', 'MedicalDepartment': '呼吸内科住院', 'MedicalInstituteCode': '11', 'MedicalInstituteName': '三峡大学咐属仁和医院', 'MedicalType': '21', 'Memo': '', 'Mobilephone': '15971663338', 'Nationality': '01', 'NowDiseaseHistory': '', 'OperatorName': '', 'OperatorNum': '', 'OtherDiagnosisCode': '', 'PathologyReport': '', 'PatientAreaNumber': '17', 'PatientType': 'N', 'PersonalIdentification': '', 'Phone': '', 'PhysicalExaminationReport': '', 'PrincipleAction': '', 'ProviderID': '', 'Pulse': '', 'Rhythm': '', 'SecondaryDiagnosisCode': 'N39.000', 'SecondaryDiagnosisName': '泌尿道感染', 'SettlementWay': '1', 'SocialInsuranceNumber': '901099033', 'SocialMedicareType': 'JD', 'SystolicPressure': '', 'TCMReport': '', 'Temperature': '', 'Weight': '', 'BankCode': '1101', 'BankName': '中国工商银行', 'AccountNumber': '111122223333', 'AccountHolder': '哈哈哈' } } } }</soa:requestData></soa:execute></soapenv:Body></soapenv:Envelope>
返回报文,如下:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><ns2:executeResponse xmlns:ns2="http://www.e-chinalife.com/soa/"><return>{"root":{"body":{"HospitalRegistrationResponse":{"Message":"success","MessageStatusCode":"10","BusinessProcessStatus":{"BusinessStatus":"1","BusinessName":"","BusinessMessage":"success!客户测试,证件号:372922731004503住院申报已成功,不能重复申报!请核对"}}},"head":{"StandardVersionCode":"1.0.0","TransactionSubCode":"00","TransactionCode":"S107","BusinessType":"3","ReceiverCode":"20161104001","SenderName":"中国人寿保险股份有限公司(宜昌)","ReceiverAddress":"","MessageDateTime":"","CorrelationId":"5919e086779a40bb3bcd89d5c27eb0373f33a180","MessageId":"201611210001","SenderAddress":"","SenderCode":"UNCL","TotalRecord":"","TransRefGUID":"201611210001","ReceiverName":"天津社保局"}}}</return></ns2:executeResponse></soap:Body></soapenv:Envelope>{"root":{"body":{"HospitalRegistrationResponse":{"Message":"success","MessageStatusCode":"10","BusinessProcessStatus":{"BusinessStatus":"1","BusinessName":"","BusinessMessage":"success!客户测试,证件号:372922731004503住院申报已成功,不能重复申报!请核对"}}},"head":{"StandardVersionCode":"1.0.0","TransactionSubCode":"00","TransactionCode":"S107","BusinessType":"3","ReceiverCode":"20161104001","SenderName":"中国人寿保险股份有限公司(宜昌)","ReceiverAddress":"","MessageDateTime":"","CorrelationId":"5919e086779a40bb3bcd89d5c27eb0373f33a180","MessageId":"201611210001","SenderAddress":"","SenderCode":"UNCL","TotalRecord":"","TransRefGUID":"201611210001","ReceiverName":"天津社保局"}}}2018-02-22 16:50:41.587 INFO 85992 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
解析获取jsonString:
{"root":{"body":{"HospitalRegistrationResponse":{"Message":"success","MessageStatusCode":"10","BusinessProcessStatus":{"BusinessStatus":"1","BusinessName":"","BusinessMessage":"success!客户测试,证件号:372922731004503住院申报已成功,不能重复申报!请核对"}}},"head":{"StandardVersionCode":"1.0.0","TransactionSubCode":"00","TransactionCode":"S107","BusinessType":"3","ReceiverCode":"20161104001","SenderName":"中国人寿保险股份有限公司(宜昌)","ReceiverAddress":"","MessageDateTime":"","CorrelationId":"5919e086779a40bb3bcd89d5c27eb0373f33a180","MessageId":"201611210001","SenderAddress":"","SenderCode":"UNCL","TotalRecord":"","TransRefGUID":"201611210001","ReceiverName":"天津社保局"}}}