最新版
我还在拥抱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,不必在意这些细节
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 比着源码来一发
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("#发起请求#");
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); \才会执行到这里,
@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 上修改后的联网带马
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); // 已经解密过了,注释掉
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 回调函数加上
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下,一些代码需要注释掉,提供些思路,仅供参考~~~
纸上得来终觉浅,绝知此事要躬行~ 多动动手写写代码,也是很好的~