工作第一次遇到对接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;
    }


}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐