美文网首页
SOAP协议之Retrofit解析

SOAP协议之Retrofit解析

作者: PuHJ | 来源:发表于2019-05-05 20:34 被阅读0次

一、前言

最近公司需要对接webservice的服务器接口,从而给了时间研究webservice的内部协议。webservice中用到的是soap协议,简单来说,soap协议就是http协议+XML格式,它是RPC调用的一种。Android中的主流http请求框架用的是OKhttp,请求解耦框架是Retrofit。既然soap是基于http协议的,那么通过Retrofit框架处理是没有问题的。

soap即简单的面向对象协议,类比onc rpc是一个基于二进制的调用,这并不利于扩展,所以之后才有了面向对象的soap协议,在XML中参数的顺序和增加并不会对之前的代码有所影响。

在网上找了些Retrofit封装代码,比较好比较入门的https://github.com/xiewenfeng/RetorfitWebServiceSample,本文也是在此基础上分析完善。

二、SOAP协议

1)、WebService请求协议

POST http://www.webxml.com.cn/WebServices/WeatherWebService.asmx HTTP/1.1
Content-Type: text/xml;charset=UTF-8
Content-Length: 347
SOAPAction: http://WebXml.com.cn/getWeatherbyCityName

 <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Body xmlns="http://WebXml.com.cn/">
      <getWeatherbyCityName>
          <theCityName>合肥</theCityName>
       </getWeatherbyCityName>
    </soap:Body>
 </soap:Envelope>

从webservice发送的协议来看,很容易看出,它是基于Http协议的,增加了header字段SOAPAction,以及将文本类型改成Content-Type: text/xml;charset=UTF-8。这样就能告诉服务器,参数类型是XML,以及调用哪个方法解析。

下面再来看看SOAP的语法结构:

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>
  ...
  ...
</soap:Header>

<soap:Body>
  ...
  ...
  <soap:Fault>
    ...
    ...
  </soap:Fault>
</soap:Body>

</soap:Envelope>

从SOAP结构中可以看到有四大块:

  • Envelope必选,可把此 XML 文档标识为一条 SOAP 消息
  • Header可选,头部信息附属功能
  • Body必选,调用信息(传递的参数)或者响应信息(返回的结果)
  • Fault可选,提供有关在处理此消息所发生错误的信息

Envelope

Envelope为根元素,没有该元素的一律不会是SOAP消息。

其中soap:Envelope中的soap是根据xmlns:soap="http://www.w3.org/2003/05/soap-envelope"而来的,它们必须一一匹配。

Body

Body元素在请求时放入传递给服务器的参数,返回时是服务器返回的数据。

2)、WebService返回协议

先看下上面的请求的返回例子:

        200 OK http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
        Content-Length: 3229
        Content-Type: application/soap+xml; charset=utf-8
        Server: Microsoft-IIS/7.5
        X-AspNet-Version: 2.0.50727
        X-Powered-By: ASP.NET
        Date: Sun, 05 May 2019 07:11:36 GMT
        OkHttp-Sent-Millis: 1557040300871
        OkHttp-Received-Millis: 1557040300923
        <?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>
                <getWeatherbyCityNameResponse xmlns="http://WebXml.com.cn/">
                    <getWeatherbyCityNameResult>
                        <string>安徽</string>
                        <string>合肥</string>
                        <string>58321</string>
                        <string>58321.jpg</string>
                        <string>2019/5/5 14:51:16</string>
                        <string>15℃/28℃</string>
                        <string>5月5日 多云</string>
                        <string>东风3-4级转东北风小于3级</string>
                        <string>1.gif</string>
                        <string>1.gif</string>
                        <string>今日天气实况:气温:27℃;风向/风力:东北风 3级;湿度:46%;紫外线强度:弱。空气质量:良。</string>
                        <string>紫外线指数:弱,辐射较弱,涂擦SPF12-15、PA+护肤品。
                                健臻·血糖指数:易波动,血糖易波动,注意监测。
                                穿衣指数:舒适,建议穿长袖衬衫单裤等服装。
                                洗车指数:较适宜,无雨且风力较小,易保持清洁度。
                                空气污染指数:良,气象条件有利于空气污染物扩散。</string>
                        <string>12℃/23℃</string>
                        <string>5月6日 多云</string>
                        <string>东风3-4级转小于3级</string>
                        <string>1.gif</string>
                        <string>1.gif</string>
                        <string>13℃/20℃</string>
                        <string>5月7日 多云转小雨</string>
                        <string>东风小于3级</string>
                        <string>1.gif</string>
                        <string>7.gif</string>
                        <string>合肥市,古称庐州,又名庐阳,位于安徽省中部,地处江淮之间、巢湖北岸,辖东市、西市、中市、郊区4区和长丰、肥东、肥西3县。总面积7266平方公里,人口425.9万。市内道路宽阔,绿树成荫,景色优美,既多现代建筑,又有名胜古迹,是一座古老而又年青的城市。合肥市位于江淮之间,处于中纬度地带,为亚热带湿润季风气候。年平均气温在15℃-16℃之间,极端最低气温-20.6℃,极端最高气温38℃以上。年平均降水量在900-1000毫米之间。全年气温变化的特点是季风明显、四季分明、气候温和、雨量适中、春温多变、秋高气爽、梅雨显著、夏雨集中,总之气候条件优越,气候资源丰富。合肥市素以“三国旧地、包拯故里”闻名于世,具有“淮右襟喉、江南唇齿”的战略地位,常为兵家必争之地。三国时魏将张辽大败孙权十万大军的逍遥津战役,即发生在这里。两千多年前,这里就已开始形成商业都会。秦、汉在此设郡县,明、清为庐州府治,民国时为安徽省省会,如今已是千樯鳞次、商贾辐凑的商业都会。合肥素有“绿色城市”、“花园城市”的美名,其环城公园便修建在合肥古城墙的基础之上,沿着起伏的岗丘地形,加之原有的绿林带及护城河,精筑而成。环城公园总长约达9公里,分为六个景区,其中较为著名的有茂林修竹,夏河朝露的银河景区;湖峦相映、水碧枫赤的西山景区;林木葱茏、芳草常青的环北景区。这样的环城公园无城墙之隔阂,面水而立,一派迷人旖旎的江南风光。</string>
                    </getWeatherbyCityNameResult>
                </getWeatherbyCityNameResponse>
            </soap:Body>
        </soap:Envelope>

从返回的可以看出来它是包含了以上的Envelope和Body,解析只需要将XML格式化成对象格式即可。

小结

从以上的协议分析,使用Retrofit请求和解析没有任何问题。请求的是Post请求,现在将请求的消息按照SOAP协议封装成符合服务器要求的格式,再将其字符串注入到post请求的Body中即可。返回的消息是个XML格式的字符串,现在只需要按照后台给定的消息去解析即可,也可以通过XML解析框架处理,这会更加简单。

三、实践Retrofit解析

引用的第三方库:

  • retrofit :网络请求框架
  • logging-interceptor : OKhttp日志打印
  • converter-simplexml : 生成及解析XML框架

1)、请求参数编写

 <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Body xmlns="http://WebXml.com.cn/">
      <getWeatherbyCityName>
          <theCityName>合肥</theCityName>
       </getWeatherbyCityName>
    </soap:Body>
 </soap:Envelope>

需要我们将代码拼接成如上的格式,其中theCityName里面的内容是传入的。

为此使用了converter-simplexml框架将对象封装成XML,建立了三个类。

// Root代表外层
@Root(name = "soap:Envelope")
@NamespaceList({
        @Namespace(reference = "http://www.w3.org/2001/XMLSchema-instance", prefix = "xsi"),
        @Namespace(reference = "http://www.w3.org/2001/XMLSchema", prefix = "xsd"),
        @Namespace(reference = "http://www.w3.org/2003/05/soap-envelope", prefix = "soap")
})
public class RequestEnvelope {
    @Element(name = "soap:Body")
    private RequestBody requestBody;

    public void setRequestBody(RequestBody requestBody) {
        this.requestBody = requestBody;
    }
}
@NamespaceList({
        @Namespace(reference = "http://WebXml.com.cn/")
})
public class RequestBody {

    @Element(name = "getWeatherbyCityName")
    private RequestModel getWeatherbyCityName;

    public void setGetWeatherbyCityName(RequestModel getWeatherbyCityName) {
        this.getWeatherbyCityName = getWeatherbyCityName;
    }
}
/**
 * 描述:参数
 * Created by PHJ on 2019/5/5.
 */
public class RequestModel {

    @Element(name = "theCityName")
    public String cityName;     //城市名字


    public void setCityName(String cityName) {
        this.cityName = cityName;
    }
}

以此转化,就是所需要的XML。并将XML放入到请求体即可。

2)、解析响应信息

        200 OK http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
        Content-Length: 3229
        Content-Type: application/soap+xml; charset=utf-8
        Server: Microsoft-IIS/7.5
        X-AspNet-Version: 2.0.50727
        X-Powered-By: ASP.NET
        Date: Sun, 05 May 2019 07:11:36 GMT
        OkHttp-Sent-Millis: 1557040300871
        OkHttp-Received-Millis: 1557040300923
        <?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>
                <getWeatherbyCityNameResponse xmlns="http://WebXml.com.cn/">
                    <getWeatherbyCityNameResult>
                        <string>安徽</string>
                        <string>合肥</string>
                        <string>58321</string>
                        <string>58321.jpg</string>
                        <string>2019/5/5 14:51:16</string>
                        <string>15℃/28℃</string>
                        <string>5月5日 多云</string>
                        <string>东风3-4级转东北风小于3级</string>
                        <string>1.gif</string>
                        <string>1.gif</string>
                        <string>今日天气实况:气温:27℃;风向/风力:东北风 3级;湿度:46%;紫外线强度:弱。空气质量:良。</string>
                        <string>紫外线指数:弱,辐射较弱,涂擦SPF12-15、PA+护肤品。
                                健臻·血糖指数:易波动,血糖易波动,注意监测。
                                穿衣指数:舒适,建议穿长袖衬衫单裤等服装。
                                洗车指数:较适宜,无雨且风力较小,易保持清洁度。
                                空气污染指数:良,气象条件有利于空气污染物扩散。</string>
                        <string>12℃/23℃</string>
                        <string>5月6日 多云</string>
                        <string>东风3-4级转小于3级</string>
                        <string>1.gif</string>
                        <string>1.gif</string>
                        <string>13℃/20℃</string>
                        <string>5月7日 多云转小雨</string>
                        <string>东风小于3级</string>
                        <string>1.gif</string>
                        <string>7.gif</string>
                        <string>合肥市,古称庐州,又名庐阳,位于安徽省中部,地处江淮之间、巢湖北岸,辖东市、西市、中市、郊区4区和长丰、肥东、肥西3县。总面积7266平方公里,人口425.9万。市内道路宽阔,绿树成荫,景色优美,既多现代建筑,又有名胜古迹,是一座古老而又年青的城市。合肥市位于江淮之间,处于中纬度地带,为亚热带湿润季风气候。年平均气温在15℃-16℃之间,极端最低气温-20.6℃,极端最高气温38℃以上。年平均降水量在900-1000毫米之间。全年气温变化的特点是季风明显、四季分明、气候温和、雨量适中、春温多变、秋高气爽、梅雨显著、夏雨集中,总之气候条件优越,气候资源丰富。合肥市素以“三国旧地、包拯故里”闻名于世,具有“淮右襟喉、江南唇齿”的战略地位,常为兵家必争之地。三国时魏将张辽大败孙权十万大军的逍遥津战役,即发生在这里。两千多年前,这里就已开始形成商业都会。秦、汉在此设郡县,明、清为庐州府治,民国时为安徽省省会,如今已是千樯鳞次、商贾辐凑的商业都会。合肥素有“绿色城市”、“花园城市”的美名,其环城公园便修建在合肥古城墙的基础之上,沿着起伏的岗丘地形,加之原有的绿林带及护城河,精筑而成。环城公园总长约达9公里,分为六个景区,其中较为著名的有茂林修竹,夏河朝露的银河景区;湖峦相映、水碧枫赤的西山景区;林木葱茏、芳草常青的环北景区。这样的环城公园无城墙之隔阂,面水而立,一派迷人旖旎的江南风光。</string>
                    </getWeatherbyCityNameResult>
                </getWeatherbyCityNameResponse>
            </soap:Body>
        </soap:Envelope>

解析XML就是去除外层的包装,转化成对象,并且保存。

在此之前需要配置转化格式:

    private static Strategy strategy = new AnnotationStrategy();
    private static Serializer serializer = new Persister(strategy);

        // 设置电脑链接
        instance.retrofit = builder.baseUrl(BASE_URL)
                // 设置client
                .client(client)
                // 设置Json解析器
                .addConverterFactory(SimpleXmlConverterFactory.create(serializer))
                .build();

采用了SimpleXmlConverterFactory解析对应的XML,当然这部分也可以自己获取字符串后自己解析。

详细代码可以参考GitHub代码

相关文章

网友评论

      本文标题:SOAP协议之Retrofit解析

      本文链接:https://www.haomeiwen.com/subject/rghhoqtx.html