工作第一次遇到对接soap接口,觉得有必要记录一下,毕竟踩了不少坑,网上帖子很多但大都不全,也不可能完全满足自己的需求,于是就有了下面的代码:
除了只是借鉴,
注意事项:1.http://ip:port/xxx/xxx/soap?wsdl有些soap接口,对面是不需要穿?wsdl对接时要问出清
2. httpPost.setHeader("SOAPAction", SOAPAction); SOAPAction也要问下,或者查看接口文件,有些只要传空字符串
3.拼接报文时要注意格式,/n一类的特殊符号不能有
4.xml解析式注意编号,编号可能存在编码来回切换returnDatabase = convertToUTF8(returnDatabase);
package com.ankang.hospital.utils; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.StringEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; 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.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Slf4j public class HttpClientUtil { private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class); /** * HttpClient 调用 WebService * * @param wsUrl webService地址,格式:http://ip:port/xxx/xxx/soap?wsdl * @param StrDate 格式的入参StrDate=2023/08/02 * @return */ public static String callServiceHC(String wsUrl, String StrDate) { String xml = createSoapContent(StrDate); String returnDatabase = doPostSoap(wsUrl, xml, "");//urn:hl7-org:v3/ZDYFWTYRK // 强制将返回结果转换为 UTF-8 编码 returnDatabase = convertToUTF8(returnDatabase); return returnDatabase; } /** * 强制转换整utp-8 * @param input * @return */ public static String convertToUTF8(String input) { try { byte[] utf8Bytes = input.getBytes(StandardCharsets.UTF_8); return new String(utf8Bytes, StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); } return input; // 返回原始字符串,如果转换失败 } /** * 根据拼接 xml 字符串 * * @param StrDate * @return */ public static String createSoapContent(String StrDate) { log.info("开始拼接请求报文"); //开始拼接请求报文 StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:hl7-org:v3\">\n"); stringBuilder.append("<soapenv:Header/>"); stringBuilder.append("<soapenv:Body>"); stringBuilder.append("<urn:ZDYFWTYRK>"); stringBuilder.append("<urn:req>"); //传参action stringBuilder.append("<urn:action>"); stringBuilder.append("Z1901"); stringBuilder.append("</urn:action>"); //传参rdn stringBuilder.append("<urn:rdn>"); stringBuilder.append("SSXWGYGXT"); stringBuilder.append("</urn:rdn>"); //传参message stringBuilder.append("<urn:message><![CDATA["); stringBuilder.append("<Request>"); stringBuilder.append("<operDate>"); stringBuilder.append(StrDate); stringBuilder.append("</operDate>"); stringBuilder.append("<hoscode>"); stringBuilder.append("A001"); stringBuilder.append("</hoscode>"); stringBuilder.append("</Request>"); stringBuilder.append("]]></urn:message>"); stringBuilder.append("</urn:req>"); stringBuilder.append("</urn:ZDYFWTYRK>"); stringBuilder.append("</soapenv:Body>"); stringBuilder.append("</soapenv:Envelope>"); logger.debug("拼接后的参数\n" + stringBuilder.toString()); return stringBuilder.toString(); } /** * HTTPClient 调用 WebService * * @param url * @param soap * @param SOAPAction * @return */ public static String doPostSoap(String url, String soap, String SOAPAction) { //请求体 String retStr = ""; // 创建HttpClientBuilder HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); // HttpClient CloseableHttpClient closeableHttpClient = httpClientBuilder.build(); HttpPost httpPost = new HttpPost(url); try { httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8"); httpPost.setHeader("SOAPAction", SOAPAction); StringEntity data = new StringEntity(soap, Charset.forName("UTF-8")); httpPost.setEntity(data); CloseableHttpResponse response = closeableHttpClient.execute(httpPost); HttpEntity httpEntity = response.getEntity(); if (httpEntity != null) { // 打印响应内容 retStr = EntityUtils.toString(httpEntity, "UTF-8"); } // 释放资源 closeableHttpClient.close(); } catch (Exception e) { e.printStackTrace(); } return retStr; } public static String analyzeResult(String xmlContent) { try { // 从 xmlContent 字符串解析 XML DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); // 启用命名空间感知 DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new InputSource(new StringReader(xmlContent))); // 获取根元素 (SOAP-ENV:Envelope) Element root = doc.getDocumentElement(); // 获取 SOAP-ENV:Body 元素 Element body = null; NodeList bodyList = root.getElementsByTagName("SOAP-ENV:Body"); if (bodyList.getLength() > 0) { body = (Element) bodyList.item(0); } // 获取带有 'urn:hl7-org:v3' 命名空间的 ZDYFWTYRKResponse 元素 Element zdyfwtyrkResponse = (Element) body.getElementsByTagNameNS("urn:hl7-org:v3", "ZDYFWTYRKResponse").item(0); Element zdyfwtyrkResult = (Element) zdyfwtyrkResponse.getElementsByTagNameNS("urn:hl7-org:v3", "ZDYFWTYRKResult").item(0); // 获取 ZDYFWTYRKResult 元素中的 CDATA 内容(实际的结果数据) String cdataContent = zdyfwtyrkResult.getTextContent(); // 处理CDATA中的XML内容 Document cdataDoc = builder.parse(new InputSource(new StringReader(cdataContent))); // 将Document转换为不带BOM的字符串 String cdataXmlString = convertDocumentToStringWithoutBOM(cdataDoc); logger.debug("cdataXmlString结果: " + cdataXmlString); return cdataXmlString; } catch (ParserConfigurationException e) { // 记录异常信息到日志 log.error("XML解析器配置错误: " + e.getMessage(), e); } catch (IOException e) { // 记录 IOException 异常信息到日志 log.error("发生 IO 异常: " + e.getMessage(), e); } catch (SAXException e) { // 记录 SAXException 异常信息到日志 log.error("SAX 解析异常: " + e.getMessage(), e); } catch (TransformerException e) { log.error("XML的转换、解析和转换错误: " + e.getMessage(), e); } return null; } /** * 将 DOM Document 转换为 UTF-8 无 BOM 格式的字符串。 * * @param doc 要转换的 DOM Document。 * @return 不带 BOM 的 UTF-8 字符串表示的文档。 */ private static String convertDocumentToStringWithoutBOM(Document doc) throws TransformerException, UnsupportedEncodingException { TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); // 设置编码为 UTF-8 且不带 BOM transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); // 省略 XML 声明 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 格式化输出 // 创建一个 ByteArrayOutputStream 来保存 XML 内容 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); StreamResult result = new StreamResult(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)); // 将 Document 转换为不带 BOM 的字符串 transformer.transform(new DOMSource(doc), result); // 将 ByteArrayOutputStream 转换为字符串 return outputStream.toString("UTF-8"); } public static List<Map<String, String>> resultMap1(String soapResponse) { // 从soapResponse中提取JSON部分 int startIndex = soapResponse.indexOf("<list>"); int endIndex = soapResponse.indexOf("</list>"); String jsonPart = soapResponse.substring(startIndex + "<list>".length(), endIndex); // 将JSON转换为Map ObjectMapper objectMapper = new ObjectMapper(); try { Map<String, Object> resultMap = objectMapper.readValue(soapResponse, new TypeReference<Map<String, Object>>() { }); ; List<Map<String, Object>> resultJsonList = (List<Map<String, Object>>) resultMap.get("resultJson"); // 转换为 List<Map<String, String>> List<Map<String, String>> resultList = new ArrayList(); for (Map<String, Object> item : resultJsonList) { Map<String, String> newMap = new HashMap(); for (Map.Entry<String, Object> entry : item.entrySet()) { String key = entry.getKey(); String value = entry.getValue().toString(); newMap.put(key, value); } // 添加resultCode和resultMsg到转换后的结果 newMap.put("resultCode", resultMap.get("resultCode").toString()); newMap.put("resultMsg", resultMap.get("resultMsg").toString()); resultList.add(newMap); } // 输出转换后的结果 for (Map<String, String> item : resultList) { System.out.println("resultCode: " + item.get("resultCode")); System.out.println("resultMsg: " + item.get("resultMsg")); System.out.println("patientName: " + item.get("patientName")); System.out.println("opername: " + item.get("opername")); System.out.println("operdate: " + item.get("operdate")); System.out.println("doctor: " + item.get("doctor")); } return resultList; } catch (IOException e) { // 异常处理 e.printStackTrace(); } return null; } public static List<Map<String, String>> resultMap(String soapResponse) { // 从soapResponse中提取JSON部分 int startIndex = soapResponse.indexOf("<list>"); int endIndex = soapResponse.indexOf("</list>"); String jsonPart = soapResponse.substring(startIndex + "<list>".length(), endIndex); // 将JSON转换为Map ObjectMapper objectMapper = new ObjectMapper(); try { Map<String, Object> resultMap = objectMapper.readValue(jsonPart, new TypeReference<Map<String, Object>>() { }); List<Map<String, Object>> resultJsonList = (List<Map<String, Object>>) resultMap.get("resultJson"); // 转换为 List<Map<String, String>> List<Map<String, String>> resultList = new ArrayList(); for (Map<String, Object> item : resultJsonList) { Map<String, String> newMap = new HashMap(); for (Map.Entry<String, Object> entry : item.entrySet()) { String key = entry.getKey(); String value = entry.getValue().toString(); newMap.put(key, value); } resultList.add(newMap); } return resultList; } catch (IOException e) { // 异常处理 e.printStackTrace(); } return null; } }