webService接口对接医院lis系统接口

简介: webService接口对接医院lis系统接口

@[toc]

1、应用场景

       由于本软件使用sprongboot前后端分离框架开发,前后端接口都是通过http协议交互的。如果搭建webService服务,太麻烦了,不想弄。因此,如何在原有的基础上,可以发送和接收webService请求呢?这要从webService接口的本质出发,解决问题。
       作为javaweb开发者,http协议是最熟悉的协议了。但是,在开发医院系统的时候,业务往往需要和lis、his系统或者医疗设备对接,因此,就会接触一些http以外的协议,比如hl7协议、soup协议等。了解每个协议的本质,开发业务才能得心应手。

2、http协议简述

       http协议是最熟悉的了,超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。通常包含请求头、请求体,我们一般发送get请求或者post请求,在前后端分离模式中,数据通过json的格式发送。分别使用HttpServletRequest和HttpServletResponse来解析数据并做出响应,这是Servlet相关的内容,在接收webService请求的时候需要用到。

3、webService协议/soup简述

       http 和 webservice 都是基于TCP/IP协议的应用层协议,soup是webService的基础通信协议。
       对于新手来说只要记住这些就行了:
       webservice=soap=http+xml,webservice协议就是有http+xml组成的,其中xml中会用到wsdl,wsdl是描述语言xml中的一种格式。Soap建立在http上,说白了就是用http传送xml。
       之所以使用webService协议是为了实现跨编程语言和跨操作系统平台,webService就是现在微服务最初模样,相当于微服务间的远程调用,除了WebService外,常见的远程调用技术还有RMI(Remote method invoke)和CORBA,由于WebService的跨平台和跨编程语言特点,因此比其他两种技术应用更为广泛,但性能略低。有兴趣的可以了解一下,下面开始上代码!

4、发送webService请求

       读完上面我们知道了webService接口就是通过http协议发送xml内容,换句话说,发送一个webService请求,就是http+xml+post。将xml内容放到请求体中,以post的方式发送,这就是一个webService请求了。

4.1建立HttpUtils工具类,来发送post请求

HttpUtils工具类,注意,这里的Content-Type设置为text/xml; charset=utf-8,或者设置为application/xml也可以。

public class HttpUtils
{
   
   
    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url 发送请求的 URL
     * @param param 请求参数,请求参数应该是 xml 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param)
    {
   
   
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try
        {
   
   
            log.info("sendPost - {}", url);
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null)
            {
   
   
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
   
   
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
   
   
            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
   
   
            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
   
   
            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
   
   
            try
            {
   
   
                if (out != null)
                {
   
   
                    out.close();
                }
                if (in != null)
                {
   
   
                    in.close();
                }
            }
            catch (IOException ex)
            {
   
   
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }
}

4.2 调用医院给的url和xml内容

比如要获取病人id为11111111的信息,前端输入病人id/或者住院号之类的,后端拿到id后直接向lis发送webService请求:
请求地址:

url=http://127.0.0.1:8080/webService/soup.aspx?s=patientService

xml内容:

<?xml version="1.0" encoding="gbk"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <getPatient xmlns="http://tempuri.org/">
      <patient><![CDATA[{"patiend_id":"11111111"}]]></patient>
    </getPatient>
  </soap:Body>
</soap:Envelope>

响应示例(仅供参考):

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <LisServiceResponse xmlns="http://tempuri.org/">
         <LisServiceResult>
            {
            "code": "200",
            "data":{
                       "住院号": "11111111",
                       "姓名": "胡思源",
                       "手术费": "1000",
                       "年龄": "18"
                      }
            }
        </LisServiceResult>
      </LisServiceResponse>
   </soap:Body>
</soap:Envelope>

我们就可以在Controller中写如下代码:

     @GetMapping("/{patientId}")
    @ApiOperation("根据患者id新增患者信息")
    public AjaxResult add(@PathVariable(value = "patientId") Long patientId)
    {
   
   
    //从前端拿到患者id后,直接发送webService请求
    String url = "http://127.0.0.1:8080/webService/soup.aspx?s=patientService";
    String xml = "<?xml version=\"1.0\" encoding=\"gbk\"?>\n" +
                "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
                "  <soap:Body>\n" +
                "    <getPatient xmlns=\"http://tempuri.org/\">\n" +
                "      <patient><![CDATA[{\"patiend_id\":\"" + patientId+ "\"}]]></patient>\n" +
                "    </getPatient>\n" +
                "  </soap:Body>\n" +
                "</soap:Envelope>";
    //使用工具类发送webService请求
    String responseBody = HttpUtils.sendPost(url, xml);
    //拿到响应后,是一个xml内容的字符串,患者的信息都在xml内容中,对xml解析就行了
    //我这里和医院商量好,将患者内容以json的方式包到了xml中,所以,我直接使用截取json字符串后,采用阿里的fastjson解析成患者对象的。
    //这里按照上面提供的响应示例,供大家参考。
    responseBody = "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
            "   <soap:Body>\n" +
            "      <LisServiceResponse xmlns=\"http://tempuri.org/\">\n" +
            "         <LisServiceResult>\n" +
            "\t\t\t{\n" +
            "\t\t\t\"code\": \"200\",\n" +
            "\t\t\t\"data\":{\n" +
            "\t\t\t\t\t   \"住院号\": \"11111111\",\n" +
            "\t\t\t           \"姓名\": \"胡思源\",\n" +
            "\t\t\t           \"手术费\": \"1000\",\n" +
            "\t\t\t           \"年龄\": \"18\"\n" +
            "\t\t\t          }\n" +
            "\t\t\t}\n" +
            "</LisServiceResult>\n" +
            "      </LisServiceResponse>\n" +
            "   </soap:Body>\n" +
            "</soap:Envelope>";
            //将xml解析成json
        int startIndex = responseBody .indexOf("{");
        int endIndex = responseBody .lastIndexOf("}");
        //获取json字符串
        String substring = responseBody .substring(startIndex, endIndex + 1);
        //去除所有空白
        String whitespace = StringUtils.deleteWhitespace(substring);
        //去除字符串中的"\n", "\r", or "\r\n"
        org.apache.commons.lang3.StringUtils.chomp(whitespace);

        //在使用阿里的fastjson解析成java对象
        JSONObject jsonObject = (JSONObject) JSON.parse(jsonString);
        //获取code
        String code = jsonObject.get("code").toString();
        if ("200".equals(code)){
   
   
            //获取data信息
            String data = jsonObject.get("data").toString();
            //这里就剩解析成java对象,进行业务逻辑的编写了,就不再赘述了!
            ..............
        }else {
   
   
            //这里处理响应不为200的情况
            ...............
        }
}

5、接收webService请求

       想要接收lis系统以webService接口发送的请求,需要有webService服务,但是在Springboot+http协议外,再搭建webService服务,多少有点冗余,主要的是和lis系统对接的接口并不多,主要还是自身的业务逻辑多,这时候怎么处理呢?
       根据上面我们了解到的,webService接口的本质就是http+xml+post。从这上面出发,我们本身已经是http协议的了,post请求也可以发送和接收,唯一不同的点就是xml内容了。
       这里我们以servlet解决这个问题,servlet下有ServletRequest和ServletResponse,ServletRequest又可以直接获取请求体,而xml内容又在请求体中,这样我们就可以拿到lis系统请求中所带的内容了,问题也就解决了,不需要重新搭建webService服务。下面上代码。

5.1 创建HttpHelper工具类

这里需要注意的一点是编码问题,一定要和对方的编码方式一致,例如:StandardCharsets.UTF_8

/**
 * 通用http工具封装
 *
 * @author ruoyi
 */
public class HttpHelper
{
   
   
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class);

    public static String getBodyString(ServletRequest request)
    {
   
   
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = null;
        try (InputStream inputStream = request.getInputStream())
        {
   
   
            reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            String line = "";
            while ((line = reader.readLine()) != null)
            {
   
   
                sb.append(line);
            }
        }
        catch (IOException e)
        {
   
   
            LOGGER.warn("getBodyString出现问题!");
            e.printStackTrace();
        }
        finally
        {
   
   
            if (reader != null)
            {
   
   
                try
                {
   
   
                    reader.close();
                }
                catch (IOException e)
                {
   
   
                    LOGGER.error(ExceptionUtils.getMessage(e));
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}

5.2 在Controller中写业务逻辑

/**
     * 添加病人化验结果(对方发出webService请求)
     * @param request
     * @param response
     */
    @PostMapping("/put")
    @ApiOperation("添加病人化验结果")
    public void putBloodStorage(ServletRequest request, ServletResponse response){
   
   
        //获取bodyString
        String bodyString = HttpHelper.getBodyString(request);

        //解析soap的请求体
        //这里的做法和上面一样都是借用fastjson解析成java对象的,就不详细写了
        .................
        //如果解析成功,则执行你的插入逻辑
        .................
        //webService接口响应
        try {
   
   
            //返回soap的xml响应
            response.setStatus(200);
            response.setContentType("text/xml; charset=utf-8");
            response.setCharacterEncoding("utf-8");
            String resp = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                    "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
                    "  <soap:Body>\n" +
                    "    <getAddResponse xmlns=\"http://tempuri.org/\">\n" +
                    "      <getAddResult>\n" +
                    "                    {\"code\": \"200\",\n" +
                    "                    \"message\": \"ok\"}\n" +
                    "      </getAddResult>\n" +
                    "    </getAddResponse>\n" +
                    "  </soap:Body>\n" +
                    "</soap:Envelope>";
            response.getWriter().print(resp);
        } catch (IOException e) {
   
   
            e.printStackTrace();
        }
    }

5.3 用soupUI测试自己的webService接口是否可以成功调用

这里就不赘述了,直接放个我测试成功的图片了!
在这里插入图片描述

目录
相关文章
外部系统调用PO的webservice服务,往SAP系统发送数据,用的XISOAPAdapter的方式,出现错误
外部系统调用PO的webservice服务,往SAP系统发送数据,用的XISOAPAdapter的方式,出现错误
193 0
外部系统调用PO的webservice服务,往SAP系统发送数据,用的XISOAPAdapter的方式,出现错误
|
4月前
|
XML Java 应用服务中间件
WebService - Axis2基于JAX-WS开发WebService并发布多个WebService
WebService - Axis2基于JAX-WS开发WebService并发布多个WebService
36 0
|
4月前
|
Java 应用服务中间件 Spring
WebService - Axis2使用services.xml进行开发server与client(未与Spring整合)
WebService - Axis2使用services.xml进行开发server与client(未与Spring整合)
44 0
|
4月前
|
Java 应用服务中间件 Spring
WebService - CXF开发Server和Client(main方法测试)
WebService - CXF开发Server和Client(main方法测试)
40 0
|
Java Android开发
哇!eclipse+webservice开发实例居然这样写(有源码可用)
哇!eclipse+webservice开发实例居然这样写(有源码可用)
107 0
哇!eclipse+webservice开发实例居然这样写(有源码可用)
|
Java 应用服务中间件 Apache
webservice开发不得不知的细节,Error creating bean with name ‘org.apache.cxf.jaxws.EndpointImpl---1987203924‘
webservice开发不得不知的细节,Error creating bean with name ‘org.apache.cxf.jaxws.EndpointImpl---1987203924‘
125 0
|
缓存 应用服务中间件 数据库
python web service开发
记录第一个web python服务
9819 0
python web service开发
|
C++ 网络架构
根据wsdl使用gsoap开发webservice服务和客户端总结
基于wsdl使用gsoap开发webservice服务和客户端
1953 0
|
Web App开发 Java Apache