retrofit2調(diào)用webservice-2.基本實現(xiàn)

retrofit2調(diào)用webservice請求一共3篇
一:工具
二:通過retrofit2 進行soap請求
三:攔截器,通過retrofit2 攔截器拼接入?yún)⒑瓦^濾出返回值壹甥,使soap請求更趨向于http請求

源碼地址:https://github.com/Frank1213/retrofit-soap/blob/master/WebServiceSOAP/app/src/main/java/linc/ps/MainActivity.java

1.使用的是公共的測試接口:獲取天氣的http://www.webxml.com.cn/WebServices/WeatherWebService.asmx

原理很簡單救巷,其實就是通過把入?yún)⑵唇悠饋恚缓蟀裺oap的請求轉(zhuǎn)變?yōu)閔ttp的post請求的方式句柠,來實現(xiàn)用retrofit2來調(diào)用soap接口請求征绸。

getSupportCity接口入?yún)ⅲ?/p>

POST /WebServices/WeatherWebService.asmx HTTP/1.1
Host: www.webxml.com.cn
Content-Type: text/xml; charset=utf-8  // headers頭信息
Content-Length: length
SOAPAction: "http://WebXml.com.cn/getSupportCity"  // headers頭信息

<?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>

看到這個,先擼一個拼接入?yún)ML的幫助類:

import android.util.Log;
import java.util.Map;
/**
 * Created by Frank on 2016/12/9.
 * 拼接http請求的頭文件
 */
public class ApiNode {
    // 轉(zhuǎn)義字符-> <xxx>
    public static String toStart2(String name) {
        return "<" + name + ">";
    }
    // 轉(zhuǎn)義字符-> </xxx>
    public static String toEnd2(String name) {
        return "</" + name + ">";
    }
    // 正常字符-> <xxx>
    public static String toStart(String name) {
        return "<" + name + ">";
    }
    // 正常字符-> </xxx>
    public static String toEnd(String name) {
        return "</" + name + ">";
    }

    public static String getParameter(String namespace, 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>" +
                "    <" + namespace + " xmlns=\"http://WebXml.com.cn/\">" + sbf.toString() +
                "    </" + namespace + ">" +
                "  </soap:Body>" +
                "</soap:Envelope>";
        Log.v("test", namespace+"請求入?yún)?" + str);
        return str;
    }
}

先寫個簡單的Retrofit初始化工具

import java.util.concurrent.TimeUnit;
import linc.ps.net_common.BuildConfig;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import rx.Observable;

/**
 * Created by Frank on 2016/12/11.
 * Retrofit初始化工具,舊的模式(請求沒有用攔截器)
 */
public class AppClient {
    // 超時時間 默認(rèn)5秒
    private static final int DEFAULT_TIMEOUT = 20;

    public static Retrofit mRetrofit;
    private ApiStores apiStores;

    private AppClient() {
        if (mRetrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.retryOnConnectionFailure(true); //連接失敗后是否重新連接
            builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);

            OkHttpClient okHttpClient = builder.build();
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(BuildConfig.API_SERVER_URL)// 服務(wù)地址:"http://www.webxml.com.cn/WebServices/"
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(okHttpClient)
                    .build();
        }
        apiStores = mRetrofit.create(ApiStores.class);
    }

    //在訪問HttpMethods時創(chuàng)建單例
    private static class SingletonHolder{
        private static final AppClient INSTANCE = new AppClient();
    }

    //獲取單例
    public static AppClient getInstance(){
        return SingletonHolder.INSTANCE;
    }

    public Observable<ResponseBody> getSupportCity(String string) {
        return apiStores.getSupportCity(string);
    }
}

這里是簡單的寫俄占,所以調(diào)用接口的那一層寫在了AppClient類里面,正常應(yīng)該要再分一層的

最后是retrofit的接口層

import okhttp3.ResponseBody;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import rx.Observable;
/**
 * Created by Frank on 2016/12/9.
 * 網(wǎng)絡(luò)請求地址,舊的模式(請求沒有用攔截器)
 */
public interface ApiStores {
    // 通過省份獲取城市代碼,頭文件在第一篇都有講到
    @Headers({
            "Content-Type:text/xml; charset=utf-8",
            "SOAPAction:http://WebXml.com.cn/getSupportCity"
    })
    // 這里對應(yīng) http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?op=getWeatherbyCityName 里面的WeatherWebService
    @POST("WeatherWebService.asmx")
    Observable<ResponseBody> getSupportCity(@retrofit2.http.Body String s);
}

這里要注意的是 @Headers里面的http://WebXml.com.cn/getSupportCity 里的 getSupportCity 每個方法是不一樣的淆衷,而且每個方法必須寫一次缸榄,有點麻煩,下一章會講到攔截器的方式祝拯。

寫個button去調(diào)用-->方法如下:

    /**
     * 通過省份獲取城市代碼,無封裝
     */
    public void getSupportCityByFirst() {
        // 拼接入?yún)?        Map map = new HashMap<>();
        map.put("byProvinceName", "福建");
        String result = ApiNode.getParameter("getSupportCity", map);
        // 調(diào)用
        AppClient.getInstance().getSupportCity(result)
                .subscribeOn(Schedulers.io())// 指定 subscribe() 發(fā)生在 IO 線程
                .observeOn(AndroidSchedulers.mainThread())// 指定 Subscriber 的回調(diào)發(fā)生在主線程
                .subscribe(new Subscriber<ResponseBody>() {
                    @Override
                    public void onCompleted() {
                        Log.e("test", "---getSupportCityByFirst onCompleted--->");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("test", "---getSupportCityByFirst onError--->");
                    }

                    @Override
                    public void onNext(ResponseBody response) {
                        try {
                            String res = response.string();
                            Log.e("test", "---getSupportCityByFirst onNext str--->"+res);
                        } catch (IOException e) {
                            Log.e("test", "---getSupportCityByFirst onNext str-IOException-->"+e.getMessage());
                            e.printStackTrace();
                        }
                    }
                });
    }

最后打印出來的入?yún)ⅲ?/p>

<?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>福建</byProvinceName>
    </getSupportCity>
  </soap:Body>
</soap:Envelope>

最后打印出來的返回值:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <getSupportCityResponse xmlns="http://WebXml.com.cn/">                                                 <getSupportCityResult>
<string>福州 (58847)</string><string>廈門 (59134)</string><string>龍巖 (58927)</string><string>南平 (58834)</string><string>寧德 (58846)</string><string>莆田 (58946)</string><string>泉州 (59137)</string><string>三明 (58828)</string><string>漳州 (59126)</string>
    </getSupportCityResult>
    </getSupportCityResponse>
  </soap:Body>
</soap:Envelope>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末甚带,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子佳头,更是在濱河造成了極大的恐慌鹰贵,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件康嘉,死亡現(xiàn)場離奇詭異碉输,居然都是意外死亡,警方通過查閱死者的電腦和手機亭珍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門敷钾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人肄梨,你說我怎么就攤上這事阻荒。” “怎么了众羡?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵侨赡,是天一觀的道長。 經(jīng)常有香客問我,道長羊壹,這世上最難降的妖魔是什么蓖宦? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮舶掖,結(jié)果婚禮上球昨,老公的妹妹穿的比我還像新娘。我一直安慰自己眨攘,他們只是感情好主慰,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鲫售,像睡著了一般共螺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上情竹,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天藐不,我揣著相機與錄音,去河邊找鬼秦效。 笑死雏蛮,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的阱州。 我是一名探鬼主播挑秉,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼苔货!你這毒婦竟也來了犀概?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤夜惭,失蹤者是張志新(化名)和其女友劉穎姻灶,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诈茧,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡产喉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡渴邦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晦譬,到底是詐尸還是另有隱情,我是刑警寧澤互广,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布敛腌,位于F島的核電站卧土,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏像樊。R本人自食惡果不足惜尤莺,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望生棍。 院中可真熱鬧颤霎,春花似錦、人聲如沸涂滴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柔纵。三九已至缔杉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間搁料,已是汗流浹背或详。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留郭计,地道東北人霸琴。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像昭伸,于是被迫代替她去往敵國和親梧乘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容