Java调用参数为xml格式的接口,分析转换返回结果

写在前面

最近第一次接触到xml格式的接口,以下是自己编写的经验,铁汁们可以参考自己的项目自行修改。
完整代码已附在文章末尾,如有缺陷,欢迎评论区或私信交流。

解决思路

首先向接口提供方申请了接口文档,包含了接口地址和参数信息,先使用postman工具调用接口,分析参数和返回值。

调通接口

敏感数据,打码请见谅
postman调用结果
其中,传入参数为xml文本,参数在最中间,可以通过字符串拼接,来实现对参数的修改。

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
    <soap12:Body>
        <GetDataRtnJsonObject xmlns="http://tempuri.org/">
            <参数一>张三</参数一>
            <参数二>某单位</参数二>
            <参数三>接口授权码</参数三>
            <参数四>是否仅查询增量数据</参数四>
            <piPageIndex>页码</piPageIndex>
            <piPageSize>页行数</piPageSize>
        </GetDataRtnJsonObject>
    </soap12:Body>
</soap12:Envelope>

返回参数也为xml文本,返回结果也在最中间,可以直接通过字符串截取,再使用JSONObject.parseObject() 将json格式文本转为需要的数据结构。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <GetDataRtnJsonObjectResponse xmlns="http://tempuri.org/">
            <GetDataRtnJsonObjectResult>
            { 
              "DataCount":2,
              "PageCount":64,
              "Datas":[
                        {"ROWID":1,"ORGCODE":"001"},
                        {"ROWID":2,"ORGCODE":"002"}
               ],
              "ErrMsg":""
              }
              </GetDataRtnJsonObjectResult>
        </GetDataRtnJsonObjectResponse>
    </soap:Body>
</soap:Envelope>

代码编写

吆西,分析完输入参数和返回参数后,解决思路自然就有了。
1、接口的输入参数虽然复杂,且为xml格式,但每次仅需要更改最中间的几个参数即可。
可以编写公共方法,将查询的几个变量塞入xml文本中指定位置,组装成完整xml请求代码块。
注意:在此的输入参数为ABCD等,仅仅为了示例,铁汁们编写代码时要使用英文驼峰命名的变量名,不然以后自己都要看不懂啦QAQ

	/**
     * @Description 将请求参数,组合为XML格式
     * @Date 17:01 2023/4/27
     * @Param [A, B, C, D, page, pageSize]
     * @return java.lang.String
     **/
    private static String getXmlInfo(String A,String B,String C,int D,int page,int pageSize) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        stringBuilder.append("<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">");
        stringBuilder.append("    <soap12:Body>");
        stringBuilder.append("        <GetDataRtnJsonObject xmlns=\"http://tempuri.org/\">");
        stringBuilder.append("            <参数一>"+A+"</参数一>");
        stringBuilder.append("            <参数二>"+B+"</参数二>");
        stringBuilder.append("            <参数三>"+C+"</参数三>");
        stringBuilder.append("            <参数四>"+D+"</参数四>");
        stringBuilder.append("            <页码>"+page+"</页码>");
        stringBuilder.append("            <页行数>"+pageSize+"</页行数>");
        stringBuilder.append("        </GetDataRtnJsonObject>");
        stringBuilder.append("    </soap12:Body>");
        stringBuilder.append("</soap12:Envelope>");
        return stringBuilder.toString();
    }

2、观察返回参数,发现对我们有用的内容,只有中间被<GetDataRtnJsonObjectResult></GetDataRtnJsonObjectResult>包起来的数据,使用substring()截取出来就好啦

// 默认此时已经接收到返回值,接口的返回值用StringBuffer类型的变量resultStringBuffer存储
int beginIndex = resultStringBuffer.indexOf("<GetDataRtnJsonObjectResult>") + 28;
int endIndex = resultStringBuffer.lastIndexOf("</GetDataRtnJsonObjectResult>");
String jsonString = resultStringBuffer.toString().substring(beginIndex,endIndex);
JSONObject result = JSONObject.parseObject(jsonString);
JSONArray jsonArray = result.getJSONArray("Datas");
// 取出来的jsonArray可以使用JSONObject.parseArray()来转换为List<Map>格式
// 其中Map.class可以更改为自己项目中的实体类
// List<Map> list = JSONObject.parseArray(jsonArray.toString(),Map.class);

3、编写Java工具类,实现调用接口,并把之前的xml组装方法和解析方法,结合起来。

	/**
     * @Description 获取XML接口数据,并解析XML为jsonObject
     * @Date 16:57 2023/4/27
     * @Param [A, B, C, D, page, pageSize]
     * @return com.alibaba.fastjson.JSONObject
     **/
    public static JSONArray creatPostAndTransData(String A, String B, String C, int D, int page, int pageSize) {
        //todo 可改为从配置文件获取,或者每次都从参数中传过来,因为我的项目中url不变,所以写死在这里
        String url = "http://xxx.xxx.xxx.xxx/base/service";
        String line = "";
        // 用来存储接收到的返回值,铁汁们可以考虑下为什么用StringBuffer而不是普通的String  ^.^
        StringBuffer resultStringBuffer = new StringBuffer();
        OutputStreamWriter out = null;
        try {
        	// 根据url连接接口
            URL realUrl = new URL(url);
            URLConnection urlConnection = realUrl.openConnection();
            // 根据需要,将传来的接口参数组装为xml文本
            String xmlInfo = getXmlInfo(psAppCode,psYwxtbh,psZdbh,piFw,piPageIndex,piPageSize);
            byte[] xmlInfoBytes = xmlInfo.getBytes();
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setUseCaches(false);
            urlConnection.setRequestProperty("Content-Type","application/soap+xml; charset=utf-8");
            urlConnection.setRequestProperty("Content-length",String.valueOf(xmlInfoBytes.length));
            out = new OutputStreamWriter(urlConnection.getOutputStream());
            out.write(new String(xmlInfo.getBytes(StandardCharsets.ISO_8859_1)));
            out.flush();
            out.close();
            // 开始接收返回值
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            for (line = bufferedReader.readLine(); line != null;line = bufferedReader.readLine()) {
                resultStringBuffer.append(line);
            }
            // 从返回的文本中,截取出我们需要的内容
            int beginIndex = resultStringBuffer.indexOf("<GetDataRtnJsonObjectResult>") + 28;
            int endIndex = resultStringBuffer.lastIndexOf("</GetDataRtnJsonObjectResult>");
            String jsonString = resultStringBuffer.toString().substring(beginIndex,endIndex);
            JSONObject result = JSONObject.parseObject(jsonString);
            JSONArray jsonArray = result.getJSONArray("Datas");
            // List<Map> list = JSONObject.parseArray(jsonArray.toString(),Map.class);
            return jsonArray;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

完成喽,现在可以根据自己需要,对返回的数据进行处理啦。

完整代码

	// 可自己编写main方法测试
	public static void main(String[] args) {
        JSONArray jsonArray = creatPostAndTransData("张三","某单位","*******",0,1,10);
        List<Map> list = JSONObject.parseArray(jsonArray.toString(),Map.class);
        System.out.println(list);
    }

	/**
     * @Description 获取XML接口数据,并解析XML为jsonObject
     * @Date 16:57 2023/4/27
     * @Param [A, B, C, D, page, pageSize]
     * @return com.alibaba.fastjson.JSONObject
     **/
    public static JSONArray creatPostAndTransData(String A, String B, String C, int D, int page, int pageSize) {
        //todo 可改为从配置文件获取,或者每次都从参数中传过来,因为我的项目中url不变,所以写死在这里
        String url = "http://xxx.xxx.xxx.xxx/base/service";
        String line = "";
        // 用来存储接收到的返回值,铁汁们可以考虑下为什么用StringBuffer而不是普通的String  ^.^
        StringBuffer resultStringBuffer = new StringBuffer();
        OutputStreamWriter out = null;
        try {
        	// 根据url连接接口
            URL realUrl = new URL(url);
            URLConnection urlConnection = realUrl.openConnection();
            // 根据需要,将传来的接口参数组装为xml文本
            String xmlInfo = getXmlInfo(psAppCode,psYwxtbh,psZdbh,piFw,piPageIndex,piPageSize);
            byte[] xmlInfoBytes = xmlInfo.getBytes();
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setUseCaches(false);
            urlConnection.setRequestProperty("Content-Type","application/soap+xml; charset=utf-8");
            urlConnection.setRequestProperty("Content-length",String.valueOf(xmlInfoBytes.length));
            out = new OutputStreamWriter(urlConnection.getOutputStream());
            out.write(new String(xmlInfo.getBytes(StandardCharsets.ISO_8859_1)));
            out.flush();
            out.close();
            // 开始接收返回值
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            for (line = bufferedReader.readLine(); line != null;line = bufferedReader.readLine()) {
                resultStringBuffer.append(line);
            }
            // 从返回的文本中,截取出我们需要的内容
            int beginIndex = resultStringBuffer.indexOf("<GetDataRtnJsonObjectResult>") + 28;
            int endIndex = resultStringBuffer.lastIndexOf("</GetDataRtnJsonObjectResult>");
            String jsonString = resultStringBuffer.toString().substring(beginIndex,endIndex);
            JSONObject result = JSONObject.parseObject(jsonString);
            JSONArray jsonArray = result.getJSONArray("Datas");
            // List<Map> list = JSONObject.parseArray(jsonArray.toString(),Map.class);
            return jsonArray;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
	/**
     * @Description 将请求参数,组合为XML格式
     * @Date 17:01 2023/4/27
     * @Param [A, B, C, D, page, pageSize]
     * @return java.lang.String
     **/
    private static String getXmlInfo(String A,String B,String C,int D,int page,int pageSize) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        stringBuilder.append("<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">");
        stringBuilder.append("    <soap12:Body>");
        stringBuilder.append("        <GetDataRtnJsonObject xmlns=\"http://tempuri.org/\">");
        stringBuilder.append("            <参数一>"+A+"</参数一>");
        stringBuilder.append("            <参数二>"+B+"</参数二>");
        stringBuilder.append("            <参数三>"+C+"</参数三>");
        stringBuilder.append("            <参数四>"+D+"</参数四>");
        stringBuilder.append("            <页码>"+page+"</页码>");
        stringBuilder.append("            <页行数>"+pageSize+"</页行数>");
        stringBuilder.append("        </GetDataRtnJsonObject>");
        stringBuilder.append("    </soap12:Body>");
        stringBuilder.append("</soap12:Envelope>");
        return stringBuilder.toString();
    }

好耶,完工下班!