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

文章目录

  • 1、应用场景
  • 2、http协议简述
  • 3、webService协议/soup简述
  • 4、发送webService请求
    • 4.1建立HttpUtils工具类,来发送post请求
    • 4.2 调用医院给的url和xml内容
  • 5、接收webService请求
    • 5.1 创建HttpHelper工具类
    • 5.2 在Controller中写业务逻辑
    • 5.3 用soupUI测试自己的webService接口是否可以成功调用

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外,常见的远程调用技术还有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内容:


<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>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 = "\n" +
                "\n" +
                "  \n" +
                "    \n" +
                "       + patientId+ "\"}]]>\n" +
                "    \n" +
                "  \n" +
                "";
    //使用工具类发送webService请求
    String responseBody = HttpUtils.sendPost(url, xml);
    //拿到响应后,是一个xml内容的字符串,患者的信息都在xml内容中,对xml解析就行了
    //我这里和医院商量好,将患者内容以json的方式包到了xml中,所以,我直接使用截取json字符串后,采用阿里的fastjson解析成患者对象的。
    //这里按照上面提供的响应示例,供大家参考。
    responseBody = "\n" +
            "   \n" +
            "      \n" +
            "         \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" +
            "\n" +
            "      \n" +
            "   \n" +
            "";
            //将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 = "\n" +
                    "\n" +
                    "  \n" +
                    "    \n" +
                    "      \n" +
                    "                    {\"code\": \"200\",\n" +
                    "                    \"message\": \"ok\"}\n" +
                    "      \n" +
                    "    \n" +
                    "  \n" +
                    "";
            response.getWriter().print(resp);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

这里就不赘述了,直接放个我测试成功的图片了!
webService接口对接医院lis系统接口_第1张图片

你可能感兴趣的:(servlet,java,http)