java对接webservice接口流程

最近要对接医院his接口,记录一下从组装报文到解析报文的流程

1.根据his方接口编写接口文档

我们是his给我们一份现有的接口,自己定义需要的接口和返回的字段,让his进行开发

接口名称 通过患者两项信息获取患者信息
交易代码 10001
接口提供方 院方his系统
接口描述 根据患者信息,获取患者在医院的患者详细信息 注: 验证条件:身份证+姓名

l 请求xml文件示例

QFKJ

QFKJ

QFKJ

10001

​ 张三丰

​ 130345198003103254

l 请求参数xml节点说明

节点名称 类型 节点描述 必传
PatientName String 患者姓名
IdCard String 身份证号

l 应答消息xml文件示例

​ 0

​ 成功</ ResultContent >

​ 1

65948789

老王头

13344343355

130345198003103254

1993-09-23

五虎山大王宫

2.熟悉his的wsdl文档

一般his会提供一个wsdl接口地址,用浏览器打开是一个xml文档,开头有一下内容:

<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://a.com.cn/">
<s:element name="a">

targetNamespace 为命名空间 <s:element name=“a”>这里a的值为接口名字(一般his会给每一个调用方分配一个账户)

3.java后端引入依赖并编写相关工具类

<!-- webservice远程调用 -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
    <version>3.2.5</version>
</dependency>
<!-- xml解析依赖 -->
<dependency>
	<groupId>org.dom4j</groupId>
	<artifactId>dom4j</artifactId>
	<version>2.1.1</version>
</dependency>
<!-- xml解析依赖 -->
<dependency>
	<groupId>jaxen</groupId>
	<artifactId>jaxen</artifactId>
	<version>1.1.1</version>
</dependency>

工具类编写

发送报文工具类
@Slf4j
public class WebServiceUtil {
    //调用方法
    public static String sendRequest(String xml, String requesturl){
        log.debug("HIS入参XML:"+xml);
        try {
            JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance();
            // wsdlUrl webservice地址,加上?wsdl后缀
            Client client = clientFactory.createClient(requesturl);
            // name_space 命名空间
            QName qName = new QName(targetNamespace,localPart);
            //参数数组
            Object[] param = new Object[]{xml}; //这里的xml是你组装的xml报文
            Object[] res = client.invoke(qName, param);
            //返回结果字符串
            log.debug("HIS返回结果XML:"+res[0]);
            return String.valueOf(res[0]);
        } catch (Exception e) {
            log.debug("[" + Thread.currentThread().getName() + "|" + "WebServiceUtil.sendRequest()" + "]");
            throw new ServiceException("调用his接口报错,联系管理员");
        }
    }

}
Client client = clientFactory.createClient(requesturl);

这里的requesturl为his提供的接口地址 例如:

http://IP地址:8070/InsurSelfSvr.asmx?WSDL
QName qName = new QName(targetNamespace,localPart);

这里的targetNamespace为第一步的命名空间 localPart为第一步的接口名 可以往上查看第一步内容

xml转换工具类
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

public class XmlUtil {

    // 解析xml报文
    public static Map getRoot(String xml) throws Exception {
        Document doc= DocumentHelper.parseText(xml);
        JSONObject json=new JSONObject();
        XmlUtil.dom4j2Json(doc.getRootElement(),json);
        return JSON.parseObject(json.toString(),Map.class);
    }

    /**
     * xml转json
     * @param element
     * @param json
     */
    public static void dom4j2Json(Element element, JSONObject json){
        //如果是属性
        for(Object o:element.attributes()){
            Attribute attr=(Attribute)o;
            if(!StringUtils.isBlank(attr.getValue())){
                json.put("@"+attr.getName(), attr.getValue());
            }
        }
        List<Element> chdEl=element.elements();
        if(chdEl.isEmpty()&&!StringUtils.isBlank(element.getText())){//如果没有子元素,只有一个值
            json.put(element.getName(), element.getText());
        }

        for(Element e:chdEl){//有子元素
            if(!e.elements().isEmpty()){//子元素也有子元素
                JSONObject chdjson=new JSONObject();
                dom4j2Json(e,chdjson);
                Object o=json.get(e.getName());
                if(o!=null){
                    JSONArray jsona=null;
                    if(o instanceof JSONObject){//如果此元素已存在,则转为jsonArray
                        JSONObject jsono=(JSONObject)o;
                        json.remove(e.getName());
                        jsona=new JSONArray();
                        jsona.add(jsono);
                        jsona.add(chdjson);
                    }
                    if(o instanceof JSONArray){
                        jsona=(JSONArray)o;
                        jsona.add(chdjson);
                    }
                    json.put(e.getName(), jsona);
                }else{
                    if(!chdjson.isEmpty()){
                        json.put(e.getName(), chdjson);
                    }
                }


            }else{//子元素没有子元素
                for(Object o:element.attributes()){
                    Attribute attr=(Attribute)o;
                    if(!StringUtils.isBlank(attr.getValue())){
                        json.put("@"+attr.getName(), attr.getValue());
                    }
                }
                if(!e.getText().isEmpty()){
                    json.put(e.getName(), e.getText());
                }
            }
        }
    }

    public static String toXml(Object model, boolean isFormatOut) throws JAXBException, IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream(1024);
        marshal(model, output, isFormatOut);
        output.flush();
        return new String(output.toByteArray(), "UTF-8");
    }

    public static void marshal(Object model, OutputStream output) throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(model.getClass());
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        jaxbMarshaller.marshal(model, output);
    }

    public static void marshal(Object model, OutputStream output, boolean isFormatOut) throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(model.getClass());
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, isFormatOut);
        jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        jaxbMarshaller.marshal(model, output);
    }
解析报文工具类

这里我采用的是xml转json再转map的方法,可以参考xpath(本人尝试过,但没做出来)

这里千万注意 这个解析方法具有业务针对性 如果采用我的方法 请修改后使用
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.business.config.utils.XmlUtil;
import com.ruoyi.common.exception.ServiceException;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ReponseXml {
    // 解析xml结果报文
    public static List<Map<String, Object>> parseXml(String xml) throws Exception {
        Document doc= DocumentHelper.parseText(xml);
        JSONObject json=new JSONObject();
        XmlUtil.dom4j2Json(doc.getRootElement(),json);
        Map resultMap = JSON.parseObject(json.toString(), Map.class);
        if (!"0".equals(resultMap.get("ResultCode"))){
            throw new ServiceException((String) resultMap.get("ResultContent")); //这里ResultContent为我们业务的指定字段 以下解析具有业务独特性
        }
        List<Map<String,Object>> responseList = new ArrayList<>();
        String[] items = xml.split("Item>");
        if (items.length==1) return null;
        if (items.length==3){
            JSONObject item = json.getJSONObject("Records").getJSONObject("Item");
            responseList.add(json2map(item));
            return responseList;
        }else{
            JSONArray jsonObject = json.getJSONObject("Records").getJSONArray("Item");
            jsonObject.stream().forEach(o->{
                responseList.add(json2map((JSONObject) o));
            });
            return responseList;
        }
    }

    //解析xml请求报文
    public static Map<String, Object> parseReqXml(String xml) throws Exception {
        Document doc= DocumentHelper.parseText(xml);
        JSONObject json=new JSONObject();
        XmlUtil.dom4j2Json(doc.getRootElement(),json);
        Map resultMap = JSON.parseObject(json.toString(), Map.class);
        Map<String,Object> param = (Map<String, Object>) resultMap.get("Param");
        param.put("TransactionCode",resultMap.get("TransactionCode"));
        return param;
    }

    public static Map<String,Object> json2map(JSONObject object){
        Map<String,Object> map = new HashMap<>();
        object.entrySet().stream().forEach(o->{
            map.put(o.getKey(),o.getValue());
        });
        return map;
    }
}

4.组装xml报文类

我是一个接口对应一个实体自己一一对应的,应该有更好的方法
在这里插入图片描述

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="Request")
@Data
public class Request10002Xml {
    @XmlElement(name="ExtUserID") //账户id his提供 一般为固定值
    private String extUserID;
    @XmlElement(name="ExtUserPwd")
    private String extUserPwd; //账户密码 his提供 一般为固定值
    @XmlElement(name="ExtOrgCode")
    private String extOrgCode; //公司代码 his提供 一般为固定值
    @XmlElement(name="TransactionCode")
    private String transactionCode;  //交易代码 his提供 一般为固定值
    @XmlElement(name="Param")
    private Xml10002 param;

    public Request10002Xml (){
        WeiXinProperties properties = SpringUtils.getBean(WeiXinProperties.class);
        this.transactionCode="10002";
        this.extUserID= properties.getExtUserID();
        this.extUserPwd=properties.getExtUserPwd();
        this.extOrgCode=properties.getExtOrgCode();
    }

    @Data
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Xml10002{
        @XmlElement(name="PatientName")
        private String patientName;
        @XmlElement(name="Telephone")
        private String telephone;
        @XmlElement(name="IdCard")
        private String idCard;
        @XmlElement(name="Sex")
        private String sex;
        @XmlElement(name="Birthday")
        private String birthday;
        @XmlElement(name="Address")
        private String address;
    }

}
组装报文
Request10002Xml request10002Xml = new Request10002Xml();
Request10002Xml.Xml10002 xml10002 = new Request10002Xml.Xml10002();
xml10002.setPatientName(registerUser.getUserName());
xml10002.setTelephone(registerUser.getPhonenumber());
xml10002.setIdCard(idNumber);
xml10002.setSex(registerUser.getSex().equals("0") ? "男" : "女");
xml10002.setBirthday(DateUtils.parseDateToStr("yyyy-MM-dd", birthDay));
xml10002.setAddress(StringUtils.isBlank(registerUser.getAddress()) ? " " : registerUser.getAddress());
request10002Xml.setParam(xml10002);
//组装Xml
String reqXml = XmlUtil.toXml(request10002Xml, true);
String resultXml = WebServiceUtil.sendRequest(reqXml, properties.getHisUrl());
解析报文
//解析Xml
List<Map<String, Object>> maps = ReponseXml.parseXml(resultXml);

5.自己的业务处理

猜你喜欢

转载自blog.csdn.net/weixin_52016779/article/details/126308389