调用WebService接口,解析返回的xml字符串 您所在的位置:网站首页 webservice返回xml被转义 调用WebService接口,解析返回的xml字符串

调用WebService接口,解析返回的xml字符串

2023-08-08 23:33| 来源: 网络整理| 查看: 265

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

一、业务场景

通过调三方系统查询接口拉取数据,生成本方系统单据。

二、实现分析

三方资管系统提供的查询接口为WebService接口,与http接口不同的是,WebService使用XML来封装数据,所以通过将接口返回的[xml]格式字符串转为Document对象和Json对象两种方式,来解析数据。

三、实现过程 1. 查看调用方法

接口地址:http://ip:port/FDLKF_OUTER/webservice/TxServiceGateway?wsdl

根据接口的wsdl文档可以知道调用的接口方法:send

image.png

2. 查看调用格式 通过SoapUI工具解析,可查看调用接口参数的SOAP格式

image.png

封装xml请求参数 public static String getXML() { //公共请求参数 String code = "9002"; long batchNo = System.currentTimeMillis(); String nodeId = "client.001"; String channelId = "RJ_NC"; Date d=new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmssSSS"); String txDateTime=sdf.format(d); SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd"); Calendar nowTime = Calendar.getInstance(); String queryStartDate = sdf1.format(nowTime.getTime()); String soapXML = "\r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " "+ code +"\r\n" + " "+ batchNo +"\r\n" + " "+ nodeId +"\r\n" + " \r\n" + " "+ channelId +"\r\n" + " \r\n" + " \r\n" + " "+ txDateTime +"\r\n" + " \r\n" + " \r\n" + " \r\n" + " "+ channelId +"\r\n" + " "+ queryStartDate +"\r\n" + " "+ queryStartDate +"\r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " ]]>\r\n" + " \r\n" + " \r\n" + " \r\n" + ""; return soapXML; } 复制代码 3. 调用接口 使用post直接请求,以下调用接口工具类 package nc.data.json.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import org.apache.log4j.Logger; import org.json.JSONObject; import org.json.XML; /** * @version 1.0.0 * @ClassName SoapUtil.java * @Description webservice调用工具类 * @createTime 2022/6/19 14:37 */ public class SoapUtil { /** * 发送http post调用webservice * * @param strUrl * @param body * @return * @throws IOException */ public static String soapPost(String strUrl, String requestBody) throws Exception { HttpURLConnection httpURLConnection = null; BufferedReader br = null; StringBuilder sb = new StringBuilder(); //1.创建服务地址,不是WSDL地址 try { URL url = new URL(strUrl); //2.打开一个通向服务地址的连接 URLConnection conn = url.openConnection(); httpURLConnection = (HttpURLConnection) conn; //3.设置参数 // 设置连接超时时间和读取超时时间 httpURLConnection.setConnectTimeout(60 * 1000); httpURLConnection.setReadTimeout(60 * 1000); httpURLConnection.setRequestMethod("POST"); // 设置请求方式 httpURLConnection.setRequestProperty("content-type", "text/xml;"); // 发送POST请求必须设置如下两行 httpURLConnection.setDoOutput(true); // 是否有出参 httpURLConnection.setDoInput(true); // 是否有入参 // 4.通过流的方式将请求体发送出去: OutputStream out = httpURLConnection.getOutputStream(); out.write(requestBody.getBytes()); out.close(); // 5.服务端返回正常: int responseCode = httpURLConnection.getResponseCode(); if (responseCode == 200) {// 服务端返回正常 InputStream is = httpURLConnection.getInputStream(); br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String temp = null; while(null != (temp = br.readLine())){ sb.append(temp); } is.close(); }else { throw new Exception("调用查询接口失败:服务器端返回HTTP code " + responseCode ); } return sb.toString(); //数据格式为xml字符串 } catch (Exception e) { throw new Exception(e.getMessage()); } finally { if (httpURLConnection != null) { httpURLConnection.disconnect(); } if (br != null) { br.close(); } } } } 复制代码

说明:读取响应数据的字节流InputStream原本是按字节数组转为字符串方式,但在和三方系统联调测试过程中,出现了个别中文乱码的情况,后来将字节流转为字符流InputStreamReader的方式成功解决。

字节流个别中文乱码

InputStream is = httpURLConnection.getInputStream(); byte[] b = new byte[1024]; StringBuffer sb = new StringBuffer(); int len = 0; while ((len = is.read(b)) != -1) { String str = new String(b, 0, len, "UTF-8"); sb.append(str); } 复制代码

字节流转为字符流成功解决乱码

InputStream is = httpURLConnection.getInputStream(); InputStreamReader isr = new InputStreamReader(is, "UTF-8"); BufferedReader br = new BufferedReader(isr); StringBuilder sb = new StringBuilder(); String temp = null; while(null != (temp = br.readLine())){ sb.append(temp); } 复制代码 返回的xml字符串response数据如下

image.png

4. 解析xml数据

解析xml数据方式有两种,将xml字符串转为Document对象和Json对象进行数据处理

将xml字符串转为Document对象 public static List convertXmlIntoDocumentObject(String response) { List elements = new ArrayList(); try { // 将xml格式的字符串解析为Document对象 Document document = DocumentHelper.parseText(response); // 获取文档根节点 Element root = document.getRootElement(); // 输出根标签的名字 System.out.println(root.getName()); // 获取根节点下面的所有子节点(不包过子节点的子节点) List element = root.elements(); Element Body = element.get(0); Element sendResponse = (Element)Body.elements().get(0); Element returnMessage = (Element)sendResponse.elements().get(0); //xml字符串 String xml = returnMessage.getText(); SAXReader reader = new SAXReader(); Document xmlDocument = reader.read(new StringReader(xml)); Element fdlk = xmlDocument.getRootElement(); if(fdlk.elementText("resultCode").equals("000000")){ Element data = fdlk.element("data").element("data"); elements = data.elements("detaillist"); } } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } return elements; } 复制代码 将xml字符串转为Json对象 /** * 传字符串格式的xml 将xml格式装换成 再将xml装换成属性没有带"@"的JSONObject格 * */ public static JSONObject convertXmlIntoJSONObject(String response) { try { //使用hutool工具类,取出在xml结点中的最终数据 JSONObject json = XML.toJSONObject(response); //xml字符串 String xml = json.getJSONObject("soap:Envelope").getJSONObject("soap:Body").getJSONObject("ns2:sendResponse").getString("returnMessage"); Document xmlDocument = DocumentHelper.parseText(xml); OutputFormat format = new OutputFormat(); format.setEncoding("UTF-8"); format.setExpandEmptyElements(true); StringWriter out = new StringWriter(); XMLWriter writer = new XMLWriter(out, format); try { writer.write(xmlDocument); writer.flush(); } catch (IOException e) { e.printStackTrace(); } // out.toString() 此结果为xml的格式 JSONObject jsonObject = XML.toJSONObject(out.toString()); } catch (DocumentException e1) { e1.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } 复制代码

注意:用XML.toJSONObject()转为JSON数据时,当detaillist只有一条数据时,会转换为一个JSON对象;当detaillist大于一条数据时,会转为一个JSON数组

/** * 处理请求返回数据 * @param response * @return * @throws BusinessException */ private String handleData(JSONObject jsonObject) throws Exception { String errmsg = ""; JSONObject fdlk = jsonObject.getJSONObject("fdlk"); String resultCode = fdlk.getString("resultCode"); if(resultCode.equals("0")){ JSONObject data = fdlk.getJSONObject("data").getJSONObject("data"); if(data.getInt("count") > 0){ if(data.getInt("count") == 1){ JSONArray jsonArray = new JSONArray(); //当detaillist只有一条数据时,为一个JSON对象 jsonArray.put(data.getJSONObject("detaillist")); errmsg = addBill(jsonArray); }else{ //当detaillist大于一条数据时,为一个JSON数组 JSONArray jsonArray = data.getJSONArray("detaillist"); errmsg = addBill(jsonArray); } } } return errmsg; } 复制代码


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有