參考
1、結合Retrofit使用post請求訪問WebService
2、retrofit2調(diào)用webservice-2.基本實現(xiàn)
前言
1匹涮、首先不要把這個想的太復雜,它就是使用【soap】協(xié)議的請求槐壳,數(shù)據(jù)格式都是【xml】然低,基礎還是http的post請求,但是它的規(guī)范顯然更多一些宏粤,總體逃不過【Request和Response】脚翘。
2、以下所有的范例都是使用 【 WeatherWebService 】 這個網(wǎng)站绍哎,它提供了【Soap1.1 和 Soap1.2 】的請求范例来农,有【Request和Response】報文可看,這樣更好理解規(guī)范和格式
一崇堰、WebService 基礎與注意點(第一次用的話稍微看看)
有soap1.1,soap1.2的區(qū)別沃于,請求的header不同,xml的內(nèi)容也略有不同啦~~
跳轉閱讀》》》【 WebService 基礎知識點和用Postman調(diào)試】海诲,復制了部分內(nèi)容過來
Soap1.1:
1繁莹、xmlns后基本都是namespace,比如envelopse標簽有三個namespace特幔,getSupportCity這個方法名有一個namespace
2咨演、區(qū)分soap1.1的是:【xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"】
3、soap1.1的請求header有:【Content-Type: text/xml; charset=utf-8 】和【SOAPAction: "http://WebXml.com.cn/getSupportCity"】
//-------------------------------------Request------------------------------------
POST /WebServices/WeatherWebService.asmx HTTP/1.1
Host: www.webxml.com.cn
Content-Type: text/xml; charset=utf-8 //header中的哦~~
Content-Length: length
SOAPAction: "http://WebXml.com.cn/getSupportCity" //header中的哦~~
<?xml version="1.0" encoding="utf-8"?>
<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/"> //標記為soap1.1協(xié)議
<soap:Body>
<getSupportCity xmlns="http://WebXml.com.cn/"> //method和其namespace
<byProvinceName>string</byProvinceName> //param
</getSupportCity>
</soap:Body>
</soap:Envelope>
//-------------------------------------Response------------------------------------
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<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>
<getSupportCityResponse xmlns="http://WebXml.com.cn/"> //結果集啦~~
<getSupportCityResult>
<string>string</string>
<string>string</string>
</getSupportCityResult>
</getSupportCityResponse>
</soap:Body>
</soap:Envelope>
Soap1.2:
1蚯斯、略薄风,同上
2、區(qū)分soap1.2的是:【xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"】
3拍嵌、soap1.2的請求header有:【application/soap+xml; charset=utf-8 】和沒有【SOAPAction】
//-------------------------------------Requeset------------------------------------
POST /WebServices/WeatherWebService.asmx HTTP/1.1
Host: www.webxml.com.cn
Content-Type: application/soap+xml; charset=utf-8 //header中的遭赂,與soap1.1不同哦,而且沒有soapaction了横辆,需要注意~~~~
Content-Length: length
<?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"> //標記為soap1.2協(xié)議
<soap12:Body>
<getSupportCity xmlns="http://WebXml.com.cn/">
<byProvinceName>string</byProvinceName>
</getSupportCity>
</soap12:Body>
</soap12:Envelope>
//-------------------------------------Response------------------------------------
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?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>
<getSupportCityResponse xmlns="http://WebXml.com.cn/"> //結果集~~~
<getSupportCityResult>
<string>string</string>
<string>string</string>
</getSupportCityResult>
</getSupportCityResponse>
</soap12:Body>
</soap12:Envelope>
二撇他、實例
1、公共部分
(1)app 的 builde.gradle添加依賴庫
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'com.squareup.retrofit2:retrofit:2.2.0'
//retrofit - webservice
compile('com.squareup.retrofit2:converter-simplexml:2.2.0') {
exclude group:'xpp3',module:'xpp3'
exclude group:'stax',module:'stax-api'
exclude group:'stax',module:'stax'
}
compile'com.squareup.retrofit2:converter-scalars:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
(2)Retrofit的訪問工具類
/**
* Retrofit
* Created by wujn on 2018/5/25.
*
* request : webservice soap
* response : xml data
*/
public class RetrofitSoapClient {
//public ZYDApiService service;
public SoapApiService service;
private RetrofitSoapClient(){
//okhttp log : 包含header狈蚤、body數(shù)據(jù)
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {LogUtil.i("RetrofitLog","retrofitBack = "+message);}
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//okhttp client
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.build();
//retrofit client
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.addConverterFactory(ScalarsConverterFactory.create()) //添加 String類型[ Scalars (primitives, boxed, and String)] 轉換器
.addConverterFactory(SimpleXmlConverterFactory.create()) //添加 xml數(shù)據(jù)類型 bean-<xml
.addConverterFactory(GsonConverterFactory.create()) //添加 json數(shù)據(jù)類型 bean->json
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl("http://www.webxml.com.cn") //test baseurl 困肩;http://www.webxml.com.cn/WebServices/
.build();
service = retrofit.create(SoapApiService.class);
}
private static RetrofitSoapClient INSTANCE = null;
//獲取單例
public static RetrofitSoapClient getInstance() {
if(INSTANCE == null){
INSTANCE = new RetrofitSoapClient();
}
return INSTANCE;
}
}
--------------------------------------------------------------------------------------------
2、從簡單的開始脆侮,能訪問上有數(shù)據(jù)返回就不錯了锌畸。
2.1、簡單的soap1.1和1.2的訪問
2.1.1他嚷、接口類
1蹋绽、RequestBody和ResponseBody的基本參數(shù)不用說
2芭毙、根據(jù)網(wǎng)站提供的范例,soap1.1和soap1.2的RequestHeader是不一樣的卸耘,對應的@Body中的ResquetBody也是不一樣的
/**
* Created by wujn on 2018/5/25.
* Version : v1.0
* Function: http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
* 用來測試的
*
* * 有幾點需要注意:
* 1退敦、endpoint(baseurl-wsdl) : 不同使用中.wsdl或者?wsdl可以去掉
* 2、namespace
* 3蚣抗、soapaction
* 4侈百、method
*
* Soap1.1
* 格式:xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
* 請求頭:1、Content-Type:text/xm;charset=UTF-8 2翰铡、SOAPAction= Namespace + Method
*
* Soap1.2
* 格式:xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"
* 請求頭:1钝域、Content-Type:application/soap+xml;charset=UTF-8 2、無SOAPAction
*
*/
public interface SoapApiService {
//--------------------------原始---------------------------------
//soap1.1
@Headers({"Content-Type:text/xml; charset=utf-8",
"SOAPAction:http://WebXml.com.cn/getSupportCity" })
@POST("/WebServices/WeatherWebService.asmx")
Observable<ResponseBody> getSupportCity_11(@Body String s);
//soap1.2
@Headers({"Content-Type:application/soap+xml;charset=UTF-8" })
@POST("/WebServices/WeatherWebService.asmx")
Observable<ResponseBody> getSupportCity_12(@Body String s);
}
2.1.2锭魔、具體請求訪問
這里一定要注意例证,有一個坑,就是在RetrofitSoapClient中的轉換中必須加上
【.addConverterFactory(ScalarsConverterFactory.create())】否則傳的string會混亂迷捧,不符合soap協(xié)議格式织咧,然后一種報錯,說SoapVersion用錯啥的~~((((ToT)?~~這個著實浪費了一點時間
/**
* 原始soap1.1訪問:把請求的requestbody全部用string弄出來
* 注意全是xml形式的string漠秋,需要添加 addConverterFactory(ScalarsConverterFactory.create()) 否則有亂七八糟的符號
* */
public void testOrgSoap11(View v){
String soap11 = "<?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" +
" <getSupportCity xmlns=\"http://WebXml.com.cn/\">\n" +
" <byProvinceName>福建</byProvinceName>\n" +
" </getSupportCity>\n" +
" </soap:Body>\n" +
"</soap:Envelope>";
addRxDestroy(RetrofitSoapClient.getInstance().service
.getSupportCity_11(soap11) //its body
.compose(RxSchedulers.<ResponseBody>io_main())
.subscribeWith(new DisposableObserver<ResponseBody>() {
@Override
public void onNext(ResponseBody responseBody) {
try {
String result = responseBody.string();
LogUtil.d("testOrgSoap11 : webservice response result = \n"+result);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
LogUtil.e("testOrgSoap11 : ex="+e.getMessage());
}
@Override
public void onComplete() {}
}));
}
/**
* 原始soap1.2訪問:把請求的requestbody全部用string弄出來
* 注意全是xml形式的string笙蒙,需要添加 addConverterFactory(ScalarsConverterFactory.create()) 否則有亂七八糟的符號
* */
public void testOrgSoap12(View v){
String soap12 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<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\">\n" +
" <soap12:Body>\n" +
" <getSupportCity xmlns=\"http://WebXml.com.cn/\">\n" +
" <byProvinceName>江蘇</byProvinceName>\n" +
" </getSupportCity>\n" +
" </soap12:Body>\n" +
"</soap12:Envelope>";
addRxDestroy(RetrofitSoapClient.getInstance().service
.getSupportCity_12(soap12) //its body
.compose(RxSchedulers.<ResponseBody>io_main())
.subscribeWith(new DisposableObserver<ResponseBody>() {
@Override
public void onNext(ResponseBody responseBody) {
try {
String result = responseBody.string();
LogUtil.d("testOrgSoap12 : webservice response result = \n"+result);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
LogUtil.e("testOrgSoap12 : ex="+e.getMessage());
}
@Override
public void onComplete() {}
}));
}
2.1.3、拼接工具:針對不同公司其實不一樣的
public class ApiNode {
// 正常字符-> <xxx>
public static String toStart(String name) {
return "<" + name + ">";
}
// 正常字符-> </xxx>
public static String toEnd(String name) {
return "</" + name + ">";
}
//soap 1.1
public static String getRequestBody11(String method, Map<String, String> map) {
StringBuffer sbf = new StringBuffer();
for (Map.Entry<String, String> entry : map.entrySet()) {
sbf.append(ApiNode.toStart(entry.getKey()));
sbf.append(entry.getValue());
sbf.append(ApiNode.toEnd(entry.getKey()));
}
String str = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<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>" +
" <" + method + " xmlns=\"http://WebXml.com.cn/\">" + sbf.toString() +
" </" + method + ">" +
" </soap:Body>" +
"</soap:Envelope>";
LogUtil.v(method+"Soap1.1 請求入?yún)?" + str);
return str;
}
//soap 1.2
public static String getRequestBody12(String method, Map<String, String> map) {
StringBuffer sbf = new StringBuffer();
for (Map.Entry<String, String> entry : map.entrySet()) {
sbf.append(ApiNode.toStart(entry.getKey()));
sbf.append(entry.getValue());
sbf.append(ApiNode.toEnd(entry.getKey()));
}
String str = "<?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>" +
" <" + method + " xmlns=\"http://WebXml.com.cn/\">" + sbf.toString() +
" </" + method + ">" +
" </soap12:Body>" +
"</soap12:Envelope>";
LogUtil.v(method+"Soap1.2 請求入?yún)?" + str);
return str;
}
}
--------------------------------------------------------------------------------------------
2.2庆锦、用bean的方式會不會好一點捅位,繼續(xù)哦
就是把數(shù)據(jù)封裝到bean里面,看的舒服一點搂抒,符合以前用json艇搀,resetful風格的那些請求
2.2.1、接口類:RequestEnvelope11 和ResponseEnvelope11需要看一下
public interface SoapApiService {
//-----------------------------繼續(xù)封裝-------------------------------------
//soap1.1
@Headers({
"Content-Type:text/xml; charset=utf-8",
"SOAPAction:http://WebXml.com.cn/getSupportCity"
})
@POST("/WebServices/WeatherWebService.asmx")
Observable<ResponseEnvelope11> getSupportCity_11_model_2(@Body RequestEnvelope11 requestEnvelope11);
}
2.2.2燕耿、所有RequestBody相關的類中符,這里面一層層東西請參考最上面的報文姜胖,當然代碼注釋里也有誉帅,所有的root,element,namespace需要對應上哦~~
(1)、最外層envelopse
/**
* Created by wujn on 2018/5/27.
* Version : v1.0
* Function: whether webservice request envelope
*
<?xml version="1.0" encoding="utf-8"?>
<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>
<getSupportCity xmlns="http://WebXml.com.cn/">
<byProvinceName>string</byProvinceName>
</getSupportCity>
</soap:Body>
</soap:Envelope>
*/
//Soap 1.1
//request的根目錄標簽
@Root(name = "soap:Envelope" , strict = false)
//Soap 1.1 根標簽的namespace
@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://schemas.xmlsoap.org/soap/envelope/", prefix = "soap")
})
public class RequestEnvelope11 {
//第一級子標簽body
@Element(name = "soap:Body", required = false)
private RequestBody11 requestBody11;
public RequestBody11 getRequestBody11() {
return requestBody11;
}
public void setRequestBody11(RequestBody11 requestBody11) {
this.requestBody11 = requestBody11;
}
}
(2)右莱、envelopse內(nèi)的body層
/**
* Created by wujn on 2018/5/27.
* Version : v1.0
* Function: whether webservice request body
*
<soap:Body>
<getSupportCity xmlns="http://WebXml.com.cn/">
<byProvinceName>string</byProvinceName>
</getSupportCity>
</soap:Body>
*/
@Root(name = "soap:Body", strict = false)
public class RequestBody11 {
@Element(name = "getSupportCity", required = false)
private RequestSupportCityBean requestSupportCityBean;
public RequestSupportCityBean getRequestSupportCityBean() {
return requestSupportCityBean;
}
public void setRequestSupportCityBean(RequestSupportCityBean requestSupportCityBean) {
this.requestSupportCityBean = requestSupportCityBean;
}
}
(3)蚜锨、body內(nèi)的請求方法getSupportCity,還有方法內(nèi)的參數(shù)byProvinceName
/**
* Created by wujn on 2018/5/27.
* Version : v1.0
* Function: whether webservice request method
*
<getSupportCity xmlns="http://WebXml.com.cn/">
<byProvinceName>string</byProvinceName>
</getSupportCity>
*/
@Root(name = "getSupportCity", strict = false)
@Namespace(reference = "http://WebXml.com.cn/")
public class RequestSupportCityBean {
@Element(name = "byProvinceName" , required = false)
private String byProvinceName;
public String getByProvinceName() {
return byProvinceName;
}
public void setByProvinceName(String byProvinceName) {
this.byProvinceName = byProvinceName;
}
}
2.2.3慢蜓、所有ResponseBody相關的類亚再,這里面一層層東西請參考最上面的報文,當然代碼注釋里也有晨抡,所有的root,element,namespace需要對應上哦~~
注意:坑氛悬,這里的Body層则剃,用的是name="Body"不是name="soap:Body",否則結果中的body=null如捅,不知道為什么棍现,有大神能解釋下么,為什么不按照報文來~~~
(1)镜遣、最外層envelopse :@Element(name = "Body", required = false)
/**
* Created by wujn on 2018/5/27.
* Version : v1.0
* Function: whether webservice response envelope
*
<?xml version="1.0" encoding="utf-8"?>
<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>
<getSupportCityResponse xmlns="http://WebXml.com.cn/">
<getSupportCityResult>
<string>string</string>
<string>string</string>
</getSupportCityResult>
</getSupportCityResponse>
</soap:Body>
</soap:Envelope>
*/
//Soap 1.1
//request的根目錄標簽
@Root(name = "soap:Envelope" , strict = false)
//Soap 1.1 根標簽的namespace
@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://schemas.xmlsoap.org/soap/envelope/", prefix = "soap")
})
public class ResponseEnvelope11 {
//第一級子標簽body
//************** this is Body , not soap:Body **************
@Element(name = "Body", required = false)
public ResponseBody11 responseBody11;
public ResponseBody11 getResponseBody11() {
return responseBody11;
}
public void setResponseBody11(ResponseBody11 responseBody11) {
this.responseBody11 = responseBody11;
}
}
(2)己肮、envelopse內(nèi)的body層:@Root(name = "Body", strict = false) //this is Body , not soap:Body
/**
* Created by wujn on 2018/5/27.
* Version : v1.0
* Function: whether webservice response body
*
<soap:Body>
<getSupportCityResponse xmlns="http://WebXml.com.cn/">
<getSupportCityResult>
<string>string</string>
<string>string</string>
</getSupportCityResult>
</getSupportCityResponse>
</soap:Body>
*/
@Root(name = "Body", strict = false) //this is Body , not soap:Body
public class ResponseBody11 {
@Element(name = "getSupportCityResponse", required = false)
public ResponseSupportCityBean responseSupportCityBean;
public ResponseSupportCityBean getResponseSupportCityBean() {
return responseSupportCityBean;
}
public void setResponseSupportCityBean(ResponseSupportCityBean responseSupportCityBean) {
this.responseSupportCityBean = responseSupportCityBean;
}
}
(3)、body下具體的response
/**
* Created by wujn on 2018/5/27.
* Version : v1.0
* Function: whether webservice response result
*
<getSupportCityResponse xmlns="http://WebXml.com.cn/">
<getSupportCityResult>
<string>string</string>
<string>string</string>
</getSupportCityResult>
</getSupportCityResponse>
*/
@Root(name = "getSupportCityResponse" )
@Namespace(reference = "http://WebXml.com.cn/")
public class ResponseSupportCityBean {
// @Attribute(name = "xmlns", empty = "http://WebXml.com.cn/", required = false)
// public String nameSpace;
@Element(name="getSupportCityResult" )
public ResponseCityBean cityBeen;
public ResponseCityBean getCityBeen() {
return cityBeen;
}
public void setCityBeen(ResponseCityBean cityBeen) {
this.cityBeen = cityBeen;
}
}
(4)悲关、response下的結果集谎僻,還比較簡單,就一個element下面多組數(shù)據(jù)
/**
* Created by wujn on 2018/5/27.
* Version : v1.0
* Function: whether webservice response result detail...
*
<getSupportCityResult>
<string>string</string>
<string>string</string>
</getSupportCityResult>
*/
@Root(name = "getSupportCityResult" )
public class ResponseCityBean {
@ElementList(name = "string" , inline = true)
public List<String> city;
public List<String> getCity() {
return city;
}
public void setCity(List<String> city) {
this.city = city;
}
}
2.2.4寓辱、具體訪問
/**
* soap1.1:封裝的bean的requestbody 和 responsebody
*
* */
public void testModelSoap11(View v){
//webservice的 request 請求參數(shù):一層層的
RequestSupportCityBean requestSupportCityBean = new RequestSupportCityBean();
requestSupportCityBean.setByProvinceName("浙江");
RequestBody11 requestBody11 = new RequestBody11();
requestBody11.setRequestSupportCityBean(requestSupportCityBean);;
RequestEnvelope11 requestEnvelope11 = new RequestEnvelope11();
requestEnvelope11.setRequestBody11(requestBody11);
addRxDestroy(RetrofitSoapClient.getInstance().service
.getSupportCity_11_model(requestEnvelope11) //its body
.compose(RxSchedulers.<ResponseEnvelope11>io_main())
.subscribeWith(new DisposableObserver<ResponseEnvelope11>() {
@Override
public void onNext(ResponseEnvelope11 responseEnvelope11) {
LogUtil.d("testModelSoap11 : response callback");
//封裝的請求bean艘绍,返回的響應也是成功的,有數(shù)據(jù)
//model data : ResponseBody callback success
if(responseEnvelope11 == null){
LogUtil.e("testModelSoap11 : ResponseEnvelope11 Null");
return;
}
ResponseBody11 responseBody11 = responseEnvelope11.getResponseBody11();
if(responseBody11 == null){
LogUtil.e("testModelSoap11 : ResponseBody11 Null");
return;
}
ResponseSupportCityBean responseSupportCityBean = responseBody11.getResponseSupportCityBean();
if(responseSupportCityBean == null){
LogUtil.e("testModelSoap11 : ResponseSupportCityBean Null");
return;
}
ResponseCityBean citybean = responseSupportCityBean.getCityBeen();
if(citybean == null){
LogUtil.e("testModelSoap11 : citybean Null");
return;
}
List<String> citys = citybean.getCity();
StringBuilder sb = new StringBuilder();
for (String c : citys){
sb.append(c+"秫筏、 ");
}
LogUtil.d("testModelSoap11 : webservice citys = \n"+sb.toString());
tv_response_result.setText(mode+"\n"+sb.toString());
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
LogUtil.e("testModelSoap11 : ex="+e.getMessage());
}
@Override
public void onComplete() {}
}));
}
以上就是對用retrofit訪問webservice的一點感悟鞍盗,還沒有考慮繼續(xù)封裝。跳昼。
----------------------------更新 2018/5/31-----------------------------------------
3般甲、對固定響應數(shù)據(jù)的格式小小優(yōu)化
3.1、響應數(shù)據(jù):
顯然status,description,tableUpdateTime是固定格式鹅颊,updateData里面是CDATA的數(shù)據(jù)敷存,先不理他...
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<instrumentDictionaryResponse xmlns="http://www.zhiyunda.com/zydjcy" xmlns:ns2="http://www.zhiyunda.com/service/instrumentDockingService">
<status>1</status>
<description>成功</description>
<tableUpdateTime>data_dictionary:2018-05-25 11:19:52;checked_unit:2016-09-18 06:32:52;standard_limit:2016-08-15 10:27:48;</tableUpdateTime>
<updateData><![CDATA[<updatedata><table><name>data_dictionary</name><field>id, codeid, name, pid, remark, inputdate, modifydate, status, type_num</field><values><value>302|302|亞硝酸鹽|1|檢測項目|2016-08-24
..............一堆數(shù)據(jù)的省略.........
10:58:51.0|null|C|null</value></values></table>-200<table><name>standard_limit</name><field>id, inputdate, modifydate, decision_basis, max_limit, min_limit, test_basis, unit, food_type, test_item</field><values></values></table></updatedata>]]>
</updateData>
</instrumentDictionaryResponse>
</S:Body>
</S:Envelope>
3.2、響應的bean類
3.2.1堪伍、響應的最外層bean:Envelope
//Soap 1.1
//request的根目錄標簽
@Root(name = "S:Envelope" , strict = false)
//Soap 1.1 根標簽的namespace
@NamespaceList({
@Namespace(reference = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "S")
})
public class ZydResponseDictionaryEnvelope {
@Path("S:Body") //跳過body
@Element(name = "instrumentDictionaryResponse", required = false)
private ZydResponseDictionary zydResponseDictionary;
public ZydResponseDictionary getZydResponseDictionary() {
return zydResponseDictionary;
}
public void setZydResponseDictionary(ZydResponseDictionary zydResponseDictionary) {
this.zydResponseDictionary = zydResponseDictionary;
}
}
3.2.2锚烦、body下的具體返回數(shù)據(jù)的bean,此處還可以繼續(xù)優(yōu)化:@Element(name = "updateData", required = false) private String updateData; 這個可以用泛型T帝雇,暫時不用了就算是獲取CDATA的string值好了涮俄,因為轉換xml的string也可以之后用泛型T來做
@Root(name = "instrumentDictionaryResponse", strict = false)
@NamespaceList({
@Namespace(reference = "http://www.zhiyunda.com/zydjcy"),
@Namespace(reference = "http://www.zhiyunda.com/service/instrumentDockingService", prefix = "ns2")
})
public class ZydResponseDictionary {
//狀態(tài)
@Element(name = "status", required = false)
private String status;
//描述
@Element(name = "description", required = false)
private String description;
//更新時間
@Element(name = "tableUpdateTime", required = false)
private String tableUpdateTime;
//更新數(shù)據(jù) --> 這個可以用泛型T,暫時不用了就算是獲取CDATA的string值好了
@Element(name = "updateData", required = false)
private String updateData;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTableUpdateTime() {
return tableUpdateTime;
}
public void setTableUpdateTime(String tableUpdateTime) {
this.tableUpdateTime = tableUpdateTime;
}
public String getUpdateData() {
return updateData;
}
public void setUpdateData(String updateData) {
this.updateData = updateData;
}
}
3.3尸闸、API接口
@Headers({
"Content-Type:text/xml; charset=utf-8",
"SOAPAction:\"\""
})
@POST(ZYDApiConfig.POST_WSDL)
Observable<ZydResponseDictionaryEnvelope> instrumentDictionaryHandle(@Body String s);
3.4彻亲、CallBack:請求的返回值略優(yōu)化下,不管是訪問失敗吮廉,或者訪問成功苞尝,數(shù)據(jù)獲取失敗都并到一起處理了,返回就是--》成功+有效數(shù)據(jù)宦芦,失敗+提示語句
public abstract class ZydResponseDictionaryCallback extends DisposableObserver<ZydResponseDictionaryEnvelope> {
@Override
public void onNext(ZydResponseDictionaryEnvelope zydResponseDictionaryEnvelope) {
if(zydResponseDictionaryEnvelope == null){
onFailed("接口數(shù)據(jù)為空");
return;
}
ZydResponseDictionary dictionary = zydResponseDictionaryEnvelope.getZydResponseDictionary();
if (dictionary == null){
onFailed("接口數(shù)據(jù)為空");
return;
}
if(dictionary.getStatus().equals("1")){
onSuccess(dictionary.getTableUpdateTime() , dictionary.getUpdateData());
}else{
onFailed(dictionary.getDescription());
}
}
@Override
public void onError(Throwable e) {
onFailed(ApiException.handleApiExMsg(e)); //就是http code處理
}
@Override
public void onComplete() { }
public abstract void onSuccess(String tableDate,String updateData);
public void onFailed(String msg) {
}
}
3.5宙址、具體請求
String requestBodyStr = ZYDApiNode.getRequestString2InstrumentDictionaryHandle(instance ,
ZYDSpOper.getTableDate(instance));
addRxDestroy(RetrofitSoapClient.getInstance().service
.instrumentDictionaryHandle(requestBodyStr) //its body
.compose(RxSchedulers.<ZydResponseDictionaryEnvelope>io_main())
.subscribeWith(new ZydResponseDictionaryCallback() {
@Override
public void onSuccess(String tableDate, String updateData) {
//對CDATA數(shù)據(jù)做處理,這個單獨拉開來講
//后續(xù)的業(yè)務需求
}
@Override
public void onFailed(String msg) {
DialogUtil.errorDialog(instance,msg);
}
}));