最新版
我還在擁抱Eclipse,用的都是jar包,用到的jar包我放到云盤
鏈接:http://pan.baidu.com/s/1gfIf0Gj 密碼:y6eh
看完很多Retrofit2.0文章后,我豈不是要這樣干,忘了告訴你,我們線上接口不下50個吆~
為什么如下定義呢?我們的接口是https://www.xxx.xxx?data=json(加密的)這樣的吆~
1.來個獲取banner的
package api;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
import bean.BannerResp;
public interface IBannerService {
@FormUrlEncoded
@POST("/")
public Call<BannerResp> getBanner(@Field("data") String json);
}
2.來個登陸的
package api;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
import bean.BannerResp;
public interface ILoginService {
@FormUrlEncoded
@POST("/")
public Call<LoginResp> getBanner(@Field("data") String json);
}
3.來個注冊的
package api;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
import bean.BannerResp;
public interface IRegisterService {
@FormUrlEncoded
@POST("/")
public Call<RegisterResp> getBanner(@Field("data") String json);
}
4.來個評論的
package api;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
import bean.BannerResp;
public interface ICommentService {
@FormUrlEncoded
@POST("/")
public Call<CommentResp> getBanner(@Field("data") String json);
}
等等等等,大兄弟,你這樣寫累不累!!!
我打算這樣干,這事鯊魚也干了~~嘿嘿
代碼如下:
package api;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
import bean.BannerResp;
public interface Api<T> {
@FormUrlEncoded
@POST("/")
public Call<T> doPost(@Field("data") String json);
}
打造通用的接口,拒絕重復代碼我認為這樣寫不錯,一勞永逸,并且是自己的風格,絕對不是外面妖艷的貨色能比的吆~
光寫不行啊,跑起來看看哥哎,我正有此意,別急賽
國際慣例,別人家都這樣寫,我就不和別人不一樣,是的,你沒看錯,和別人寫的一樣一樣的....
構造Retrofit2君
package http;
import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import api.IBannerService;
import bean.BannerResp;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.wyhd.encry.decry.security.util.AesEncryptionUtil;
import factory.HttpLoggingInterceptor;
import factory.IGsonFactory;
public class RetrofitHelper {
/** 基本路徑 */
public static final String BASE_URL = "https://api.imeizan.cn";
public static void tst(String json) {
json = AesEncryptionUtil.encrypt(json); // 加密json,不必在意這些細節(jié)
Gson gson = new GsonBuilder().setLenient().create();
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.client(getOkHttpClient())
.addConverterFactory(IGsonFactory.create(gson)).build();
Api service = retrofit.create(Api.class);
Call<BannerResp> call = service.doPost(json);
call.enqueue(new Callback<BannerResp>() {
@Override
public void onResponse(Call<BannerResp> call,
Response<BannerResp> resp) {
BannerResp body = resp.body();
System.out.println("異步返回:" + body.toString());
}
@Override
public void onFailure(Call<BannerResp> msg, Throwable error) {
System.out.println(msg.toString() + "|" + error.getMessage());
}
});
final Call<BannerResp> clone = call.clone();
new Thread() {
public void run() {
try {
Response<BannerResp> execute = clone.execute();
System.out.println("同步返回:" + execute.body().toString());
} catch (Exception e) {
System.out.println("同步返回:" + e.getMessage());
}
};
}.start();
}
public static OkHttpClient getOkHttpClient() {
// 日志顯示級別
HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;
// 新建log攔截器
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
System.out.println(message);
}
});
loggingInterceptor.setLevel(level);
// 定制OkHttp
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
// OkHttp進行添加攔截器loggingInterceptor
httpClientBuilder.addInterceptor(loggingInterceptor);
return httpClientBuilder.build();
}
}
然后呢?媽的..當然是跑起來啊~
等等,先奉上請求,響應體,為什么那么寫?接口那樣的定義,我也很無奈啊~
- 1.banner請求體
package bean;
import java.io.Serializable;
public class BannerReq implements Serializable {
private static final long serialVersionUID = 1L;
public int num;
public String version="v1.0.0";
public String system = "360";
public BannerReq(int num) {
super();
this.num = num;
}
@Override
public String toString() {
return "BannerReq [num=" + num + ", version=" + version + ", system="
+ system + "]";
}
}
- 2.banner響應體
package bean;
import java.io.Serializable;
import java.util.List;
public class BannerResp implements Serializable {
private static final long serialVersionUID = 1L;
public int code;
public int num;
public String msg;
public List<Banner> data;
public class Banner implements Serializable {
private static final long serialVersionUID = 1L;
public String id;
public String name;
@Override
public String toString() {
return "Banner [id=" + id + ", name=" + name + "]";
}
}
@Override
public String toString() {
return "BannerResp [code=" + code + ", num=" + num + ", msg=" + msg
+ ", data=" + data + "]";
}
}
別他媽催了,這就跑了吆,萬事俱備只欠東風,bingo...
package com.july.testunit;
import http.RetrofitHelper;
import android.app.Activity;
import android.os.Bundle;
import bean.BannerReq;
import com.google.gson.Gson;
import com.july.retrfit.R;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BannerReq req = new BannerReq(1); // 接口號1是banner
Gson gson = new Gson();
String json = gson.toJson(req);
RetrofitHelper.tst(json);
}
}
運行結果如下:
Are you kidding me!!!
package api;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface Api<T> {
public final String KEY = "data";
@FormUrlEncoded
@POST("/")
public Call<T> doPost(@Field(KEY) String json);
}
這樣寫,不存在的...
改吧改吧
package api;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface Api {
public final String KEY = "data";
@FormUrlEncoded
@POST("/")
public Call<String> doPost(@Field(KEY) String json);
}
報告老板,我覺得寫成通用的應該是這樣~~
好了,廢話太多,來不及了,趕緊上車!!!
返回String吆,需要自定義GsoncovertFactory
別害怕,GsoncovertFactory人很好,說話又好聽
- 1 比著源碼來一發(fā)
package factory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
public class IGsonFactory2 extends Converter.Factory {
public static IGsonFactory2 create() {
return create(new GsonBuilder().setLenient().create());
}
public static IGsonFactory2 create(Gson gson) {
if (gson == null)
throw new NullPointerException("gson == null");
return new IGsonFactory2(gson);
}
private final Gson gson;
private IGsonFactory2(Gson gson) {
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
return new IResponseBodyConverter2(); // 響應
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations,
Retrofit retrofit) {
System.out.println("#發(fā)起請求#");
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new IRequestBodyConverter2<>(gson, adapter); // 請求
}
}
- 2 requestbody,基本不動
package factory;
import java.io.IOException;
import java.nio.charset.Charset;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Converter;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.wyhd.encry.decry.security.util.AesEncryptionUtil;
/**
* RequestBody 對請求體進行加密處理
*/
public class IRequestBodyConverter2<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType
.parse("application/json; charset=UTF-8");
static final Charset UTF_8 = Charset.forName("UTF-8");
final Gson gson;
final TypeAdapter<T> adapter;
IRequestBodyConverter2(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
System.out.println("#IRequestBodyConverter初始化#");
}
// 接口如果這樣定義 void doPost(@Body by); \才會執(zhí)行到這里,
@Override
public RequestBody convert(T value) throws IOException {
String json = value.toString();
System.out.println("#加密前#" + json);
json = AesEncryptionUtil.encrypt(json);
System.out.println("#加密后#" + json);
return RequestBody.create(MEDIA_TYPE, json);
}
}
- 3 核心代碼了
package factory;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import com.wyhd.encry.decry.security.util.AesEncryptionUtil;
public class IResponseBodyConverter2 implements Converter<ResponseBody, String> {
@Override
public String convert(ResponseBody value) throws IOException {
String string = value.string();
System.out.println("#解密前@#" + string);
string = AesEncryptionUtil.decrypt(string);
System.out.println("#解密后@#" + string);
return string;
}
}
- 4 上修改后的聯(lián)網(wǎng)帶馬
public class HttpRequestFactory {
public static final Gson GSON = new Gson();
public static final String TAG = HttpRequestFactory.class.getSimpleName();
public static final String BASE_URL = "https://api.imeizan.cn";
public static String reqParams(Object src) {
String json = "";
if (src != null && src instanceof String) {
json = (String) src;
} else {
if (src == null) {
} else {
json = GSON.toJson(src);
}
}
return json;
}
public static <T> void exec3(Object src, final ResultCallback<T> mCallback) {
String json = reqParams(src);
json = AesEncryptionUtil.encrypt(json);
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.client(getOkHttpClient())
.addConverterFactory(IGsonFactory.create(GSON)).build();
Api api = retrofit.create(Api.class);
Call<String> doPost = api.doPost(json);
doPost.enqueue(new Callback<String>() {
@Override
public void onFailure(Call<String> request, Throwable error) {
System.out.println("#失敗回調#");
if (mCallback != null) {
mCallback.onError(null, error);
}
}
@Override
public void onResponse(Call<String> call, Response<String> resp) {
System.out.println("#成功回調#");
if (mCallback != null) {
if (resp.isSuccessful()) {
String finalStr = "";
String string = resp.body();
// finalStr = AesEncryptionUtil.decrypt(string); // 已經(jīng)解密過了,注釋掉
finalStr = string;
if (mCallback.mType != null) {
if (mCallback.mType == String.class) {
if (Tools.isEmpty(finalStr)) {
Exception e = new Exception(
"AesEncryptionUtil.decrypt(string) return null!");
exeFailedCallback(call, e, mCallback);
} else {
exeSuccessCallback(finalStr, mCallback);
}
} else {
Object o = GSON.fromJson(finalStr,
mCallback.mType);
if (o == null) {
Exception e = new Exception(
"mGson.fromJson(finalStr,callback.mType) return null!");
exeFailedCallback(call, e, mCallback);
} else {
exeSuccessCallback(o, mCallback);
}
}
} else {
Throwable e = new Throwable("mCallback.mType 為空!!!");
exeFailedCallback(call, e, mCallback);
}
} else {
Throwable e = new Throwable(resp.toString());
exeFailedCallback(call, e, mCallback);
}
}
}
});
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void exeFailedCallback(final Call call, final Throwable e,
final ResultCallback<?> callback) {
if (callback != null) {
callback.onError(call, e);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void exeSuccessCallback(Object o, final ResultCallback callback) {
if (callback != null) {
callback.onResponse(o);
}
}
public static OkHttpClient getOkHttpClient() {
// 日志顯示級別
HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;
// 新建log攔截器
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
System.out.println(message);
}
});
loggingInterceptor.setLevel(level);
// 定制OkHttp
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
// OkHttp進行添加攔截器loggingInterceptor
httpClientBuilder.addInterceptor(loggingInterceptor);
return httpClientBuilder.build();
}
}
- 5 回調函數(shù)加上
package callback;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import com.google.gson.internal.$Gson$Types;
import retrofit2.Call;
public abstract class ResultCallback<T> {
public Type mType;
public ResultCallback() {
mType = getSuperclassTypeParameter(getClass());
}
static Type getSuperclassTypeParameter(Class<?> subclass) {
Type superclass = subclass.getGenericSuperclass();
if (superclass instanceof Class) {
throw new RuntimeException("Missing type parameter.");
}
ParameterizedType parameterized = (ParameterizedType) superclass;
return $Gson$Types
.canonicalize(parameterized.getActualTypeArguments()[0]);
}
public abstract void onError(Call<T> request, Throwable e);
public abstract void onResponse(T response);
}
- 6 測試
package com.july.retrfit;
import http.HttpRequestFactory;
import http.RetrofitHelper002;
import retrofit2.Call;
import android.app.Activity;
import android.os.Bundle;
import bean.BannerReq;
import bean.BannerResp;
import callback.ResultCallback;
import com.google.gson.Gson;
import com.july.retrfit.R;
import com.wyhd.common.sdk.Logger;
public class MainActivity extends Activity {
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲取banner 接口號1
BannerReq req = new BannerReq(1);
HttpRequestFactory.exec3(req, new ResultCallback<BannerResp>() {
@Override
public void onError(Call<BannerResp> request, Throwable e) {
Logger.log(TAG, "##失敗##" + e.getMessage());
}
@Override
public void onResponse(BannerResp response) {
Logger.log(TAG, "##成功##" + response);
}
});
//登陸接口 接口號3
LoginReq req2 = new LoginReq(3,"賬號","密碼");
HttpRequestFactory.exec3(req2, new ResultCallback<LoginResp>() {
@Override
public void onError(Call<LoginResp> request, Throwable e) {
Logger.log(TAG, "##失敗##" + e.getMessage());
}
@Override
public void onResponse(LoginResp response) {
Logger.log(TAG, "##成功##" + response);
}
});
}
}
到此為止,Retrofit2通用接口編寫完畢,運行結果???
這個,不看不行嗎?
美圖你說個杰寶,也是哈~
測試成功,不要較真
忘了說了,我還在擁抱Eclipse,你們會不會打死我....
retrofit 封裝之路(一)
鏈接:http://pan.baidu.com/s/1qXPErAO 密碼:hgqf
retrofit 封裝之路(二)
鏈接:http://pan.baidu.com/s/1bo5Mf1P 密碼:andk
retrofit 封裝之路(三) |retrofit + rxjava系
鏈接:http://pan.baidu.com/s/1o7RKoZo 密碼:zuaw
代碼量不多,jar包放在assert下,一些代碼需要注釋掉,提供些思路,僅供參考~~~
紙上得來終覺淺,絕知此事要躬行~ 多動動手寫寫代碼,也是很好的~