這天,leader給了我一張圖,然後讓我調試後臺接口,圖片如下:
我看這麼簡單,然後直接用瀏覽器測試了一下,然後返回圖片如下:
然後花了一個下午時間測試,終於把接口調通了,但是居然解析不了其中的返回內容,,,,於是,在禮拜天我就花時間來研究了一下關於接口的開發!
本來我打算隨便寫一個 Java 類,然後用tomcat就可以測試後臺了,但是我不知道如何實現上圖的禁止get請求,於是問了一下這方面的大神:
我用spring mvc的時候,controler的requestmapping的method 的值設爲post就會無視get請求
由於上面的知識點我都不會,於是我自動忽略了自己寫後臺的想法,接着打算在網上找一個可以測試後臺的網站,結果找到一個 http://www.ouapi.com/ ,但是打開頁面以後也不知道如何設置後臺,後來詢問大神得知——人家一般使用的是 postman 這個插件,於是我按照網上的介紹,趕緊安裝了一個!測試了一下,還真的很好用,以圖爲證:
廢話說了這麼多,接下來開始幹正事!介紹一下自己使用 Retrofit 2.0 的一些總結。第一步,肯定是得導包,這個隨便百度一下 Retrofit 2.0 就可以翻出來了,
compile 'com.squareup.retrofit2:retrofit:2.0.2' //retrofit:2.0
compile 'com.squareup.retrofit2:converter-gson:2.0.2' //retrofit:2.0封裝下的gson
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0' //retrofit:2.0下的okhttp3的請求日誌
第二步就是實例化 retrofit ,這個基本上也是可以直接從網上複製下來就可以用
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.retryOnConnectionFailure(true)
.connectTimeout(15, TimeUnit.SECONDS)
.addNetworkInterceptor(interceptor)
.build();
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
//獲取實例
Retrofit retrofit = new Retrofit.Builder()
//設置OKHttpClient,如果不設置會提供一個默認的
.client(client)
//設置baseUrl,必須是以“/”結尾
.baseUrl(url)
//添加Gson轉換器
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
接下來就是關於各種網絡請求的封裝了,比如我們先請求一段本地的文件,測試一下 get 請求,簡單來說我們的第三步需要如下步驟:
- 建立 interface ,並封裝 get 請求
- 通過上面實例化的 Retrofit 對象,實例化上面的 interface 對象
調用上述封裝的 get 請求
通過上面的步驟,大概知道做什麼以後,那麼我們通過 postman 來測試一下這個接口:
當然,大家也可以通過post來測試這個接口,待會我們就可以來測試,現在開始來執行上面的第一步——建立 interface ,並封裝 get 請求:
public interface RetrofitInterface {
@GET("getdata.gson")
Call<Password> getPassWord();
}
這裏說一下 @GET(“getdata.gson”) 這裏爲什麼會跟一個文件呢?因爲上面說過,
設置baseUrl,必須是以“/”結尾(重要的事情只說一邊!)
所以我們現在帶着上面的提醒來執行第二步——通過上面實例化的 Retrofit 對象,實例化上面的 interface 對象:
/**
* Retrofit實體類
* Created by asus on 2017/7/15.
*/
public class RetrofitLoader {
private RetrofitInterface service;
public RetrofitLoader(String url){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.retryOnConnectionFailure(true)
.connectTimeout(15, TimeUnit.SECONDS)
.addNetworkInterceptor(interceptor)
.build();
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
//獲取實例
Retrofit retrofit = new Retrofit.Builder()
//設置OKHttpClient,如果不設置會提供一個默認的
.client(client)
//設置baseUrl,必須是以“/”結尾
.baseUrl(url)
//添加Gson轉換器
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
service = retrofit.create(RetrofitInterface.class);
}
public void getPassWord(Callback<Password> callback){
Call<Password> call = service.getPassWord();
//異步請求
call.enqueue(callback);
//同步請求
//1call.execute();
}
}
上面的 RetrofitLoader 應該做一個單例,這裏只是測試,下來後慢慢完善!接下來就是第三步——調用上述封裝的 get 請求:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = (TextView) findViewById(R.id.textview);
Thread thread = Thread.currentThread();
Log.e(TAG, "onCreate: "+ thread.getId());
new Thread(){
@Override
public void run() {
super.run();
Thread thread = Thread.currentThread();
Log.e(TAG, "run1: "+ thread.getId());
new RetrofitLoader("http://192.168.199.237:8080/examples/").getPassWord(new Callback<Password>() {
@Override
public void onResponse(Call<Password> call,final Response<Password> response) {
textView.setText(response.body().getData());
Thread thread = Thread.currentThread();
Log.e(TAG, "onResponse: "+ thread.getId());
textView.post(new Runnable() {
@Override
public void run() {
Thread thread = Thread.currentThread();
Log.e(TAG, "run2: "+ thread.getId());
}
});
}
@Override
public void onFailure(Call<Password> call, Throwable t) {
Log.e(TAG, "onFailure: ",t );
}
});
}
}.start();
}
}
接下來我們看看日誌:
07-16 21:52:35.837 9174-9174/? E/MainActivity: onCreate: 1
07-16 21:52:35.838 9174-9195/? E/MainActivity: run1: 1248
07-16 21:52:36.076 9174-9174/? E/MainActivity: onResponse: 1
07-16 21:52:36.076 9174-9174/? E/MainActivity: onResponse: 7B7F25D86267923209A11145A4EBB34
07-16 21:52:36.086 9174-9174/? E/MainActivity: run2: 1
這裏說明一個問題:在線程裏面開子線程請求網絡(線程 ID :1248 ),然後異步返回的線程不是在當前所在的子線程,而是在主線程,至於網絡請求的同步,這個就不記錄測試了,其實我最想測試的是 Post 請求,而且是帶參數的,因爲工作中需要用到,但是在測試過程中發生問題了!
在講問題之前先看看API吧,如圖:
接下來我們先封裝一個 Post 請求,不過這裏不需要單獨新建 interface 對象了,
/**
* Created by asus on 2017/7/15.
*/
public interface RetrofitInterface {
@GET("getdata.gson")
Call<Password> getPassWord();
@POST("LookUp")
Call<IdCardResult> checkIdCard(@Body IdCardInfo cardInfo);
}
/**
* Retrofit實體類
* Created by asus on 2017/7/15.
*/
public class RetrofitLoader {
private RetrofitInterface service;
public RetrofitLoader(String url){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.retryOnConnectionFailure(true)
.connectTimeout(15, TimeUnit.SECONDS)
.addNetworkInterceptor(interceptor)
.build();
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
//獲取實例
Retrofit retrofit = new Retrofit.Builder()
//設置OKHttpClient,如果不設置會提供一個默認的
.client(client)
//設置baseUrl,必須是以“/”結尾
.baseUrl(url)
//添加Gson轉換器
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
service = retrofit.create(RetrofitInterface.class);
}
public void getPassWord(Callback<Password> callback){
Call<Password> call = service.getPassWord();
//異步請求
call.enqueue(callback);
//同步請求
//1call.execute();
}
public void checkIdCard(IdCardInfo cardInfo, Callback<IdCardResult> callback){
service.checkIdCard(cardInfo).enqueue(callback);
}
}
接下來我們看看調用過程中是不是有傳說的異常?
訪問成功了?那麼我們繼續來看看訪問不成功,只要將post方法修改一下,這個方法就運行不起來:
Call<Response> checkIdCard(@Body IdCardInfo cardInfo);
雖然 Body 標籤完成了訪問,但是返回碼是 1001,返回碼是 key 值錯誤,但是這個值我確定沒有複製錯,具體是怎麼回事呢?看看日誌:
對 http 來說參數之間的分割只有一種 & ,這裏的,是錯誤的,所以服務端報錯,那麼這裏該如何修改呢?
@FormUrlEncoded
@POST("LookUp")
Call<IdCardResult> checkIdCard(@FieldMap Map<String, String> infos);
public void checkIdCard(IdCardInfo cardInfo, Callback<IdCardResult> callback){
Map<String, String> infos = new HashMap<>();
infos.put("id",cardInfo.getId());
infos.put("key",cardInfo.getKey());
service.checkIdCard(infos).enqueue(callback);
}
接下來我們再繼續觀察一下日誌:
07-16 23:25:18.385 19518-19555/? E/MainActivity: log: --> POST http://api.avatardata.cn/IdCard/LookUp http/1.1
07-16 23:25:18.385 19518-19555/? E/MainActivity: log: Content-Type: application/x-www-form-urlencoded
07-16 23:25:18.386 19518-19555/? E/MainActivity: log: Content-Length: 58
07-16 23:25:18.387 19518-19555/? E/MainActivity: log:
07-16 23:25:18.387 19518-19555/? E/MainActivity: log: id=510921199103210310&key=af43ed19e5524c55a7bdb33d7f16bc5f
07-16 23:25:18.387 19518-19555/? E/MainActivity: log: --> END POST (58-byte body)
07-16 23:25:18.819 19518-19555/? E/MainActivity: log: <-- 200 OK http://api.avatardata.cn/IdCard/LookUp (432ms)
07-16 23:25:18.819 19518-19555/? E/MainActivity: log: Cache-Control: private
07-16 23:25:18.819 19518-19555/? E/MainActivity: log: Content-Length: 110
07-16 23:25:18.820 19518-19555/? E/MainActivity: log: Content-Type: application/json; charset=utf-8
07-16 23:25:18.820 19518-19555/? E/MainActivity: log: Server: Microsoft-IIS/7.5
07-16 23:25:18.820 19518-19555/? E/MainActivity: log: X-AspNet-Version: 4.0.30319
07-16 23:25:18.820 19518-19555/? E/MainActivity: log: X-Powered-By: ASP.NET
07-16 23:25:18.820 19518-19555/? E/MainActivity: log: Date: Sun, 16 Jul 2017 15:25:19 GMT
07-16 23:25:18.820 19518-19555/? E/MainActivity: log: OkHttp-Sent-Millis: 1500218718478
07-16 23:25:18.820 19518-19555/? E/MainActivity: log: OkHttp-Received-Millis: 1500218718818
07-16 23:25:18.821 19518-19555/? E/MainActivity: log:
07-16 23:25:18.821 19518-19555/? E/MainActivity: log: {"result":{"address":"四川省蓬溪縣","sex":"M","birthday":"1991-03-21"},"error_code":0,"reason":"Succes"}
07-16 23:25:18.821 19518-19555/? E/MainActivity: log: <-- END HTTP (110-byte body)
07-16 23:25:18.830 19518-19518/? E/MainActivity: onResponse: 0
OK,明天可以給領導交差了!!!