封装目的
规避okhttp框架API更新带来的风险
提高代码复用性
提升程序的可扩展性
封装逻辑
封装思路
1.封装request
RequestParams类
封装所有的请求参数到HashMap中(线程安全)
CommonRequest类
接受请求参数,生成request对象
RequestParams类
封装所有的请求参数到HashMap中(线程安全)
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author xiaoxu 17-07-21
* @function 封装所有的请求参数到HashMap中(线程安全)
*/
public class RequestParams {
public ConcurrentHashMap<String, String> urlParams = new ConcurrentHashMap<String, String>();
public ConcurrentHashMap<String, Object> fileParams = new ConcurrentHashMap<String, Object>();
/**
* Constructs a new empty {@code RequestParams} instance.
*/
public RequestParams () {
this ((Map<String, String>) null );
}
/**
* Constructs a new RequestParams instance containing the key/value string
* params from the specified map.
*
* @param source the source key/value string map to add.
*/
public RequestParams (Map<String, String> source) {
if (source != null ) {
for (Map.Entry<String, String> entry : source.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
}
/**
* Constructs a new RequestParams instance and populate it with a single
* initial key/value string param.
*
* @param key the key name for the intial param.
* @param value the value string for the initial param.
*/
public RequestParams (final String key, final String value) {
this (new HashMap<String, String>() {
{
put(key, value);
}
});
}
/**
* Adds a key/value string pair to the request.
*
* @param key the key name for the new param.
* @param value the value string for the new param.
*/
public void put (String key, String value) {
if (key != null && value != null ) {
urlParams.put(key, value);
}
}
public void put (String key, Object object) throws FileNotFoundException {
if (key != null ) {
fileParams.put(key, object);
}
}
public boolean hasParams () {
if (urlParams.size() > 0 || fileParams.size() > 0 ){
return true ;
}
return false ;
}
}
CommonRequest类
接受请求参数,生成request对象
import java.util.Map;
import okhttp3.FormBody;
import okhttp3.Request;
/**
* Created by xiaoxu on 2017/7/22.
*
* @function 接受请求参数,生成request对象
*/
public class CommonRequest {
/**
* @param url
* @param params
* @return 返回一个创建好的post类型request对象
*/
public static Request createPostRequest (String url, RequestParams params) {
FormBody.Builder mFormBodyBuilder = new FormBody.Builder();
if (params != null ) {
for (Map.Entry<String, String> entry : params.urlParams.entrySet()) {
mFormBodyBuilder.add(entry.getKey(), entry.getValue());
}
}
FormBody mFromBody = mFormBodyBuilder.build();
return new Request.Builder().url(url).post(mFromBody).build();
}
/**
* @param url
* @param params
* @return 返回一个get类型请求对象
*/
public static Request createGetRequest (String url, RequestParams params) {
StringBuilder urlBuilder = new StringBuilder(url).append("?" );
if (params != null ) {
for (Map.Entry<String, String> entry : params.urlParams.entrySet()) {
urlBuilder.append(entry.getKey())
.append("=" )
.append(entry.getValue())
.append("&" );
}
}
return new Request.Builder()
.url(urlBuilder.substring(0 , urlBuilder.length() - 1 ))
.get()
.build();
}
}
2.封装client
CommonOkthhpClient类
请求体发送,请求参数的配置,https的支持
import com.yingyuliuliwan.liuliwansdk.okhttps.https.HttpsUtils;
import com.yingyuliuliwan.liuliwansdk.okhttps.response.CommonJsonCallback;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
/**
* Created by xiaoxu on 2017/7/22.
*
* @function 请求体发送,请求参数的配置,https的支持
*/
public class CommonOkthhpClient {
private static final int TIME_OUT = 30000 ;
private static OkHttpClient mOkHttpClient;
static {
OkHttpClient.Builder okhttpBulider = new OkHttpClient.Builder();
okhttpBulider.connectTimeout(TIME_OUT, TimeUnit.SECONDS);
okhttpBulider.readTimeout(TIME_OUT, TimeUnit.SECONDS);
okhttpBulider.writeTimeout(TIME_OUT, TimeUnit.SECONDS);
okhttpBulider.followRedirects(true );
okhttpBulider.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify (String hostname, SSLSession session) {
return true ;
}
});
okhttpBulider.sslSocketFactory(HttpsUtils.initSSLSocketFactory());
mOkHttpClient = okhttpBulider.build();
}
public static Call sendRequest (Request request, CommonJsonCallback commonCallBack){
Call call = mOkHttpClient.newCall(request);
call.enqueue(commonCallBack);
return call;
}
}
3.封装response
DisposeDataListener类
自定义监听事件,回调事件处理
DisposeDataHandle类
将回调监听对象和要转化的字节码进行封装
CommonJsonCallback类
处理json的回调响应
ResponseEntityToModule类
将json对象转化为实体类对象(也可以使用第三方库)
DisposeDataListener类
自定义监听事件,回调事件处理
/**
* Created by xiaoxu on 2017/7/23.
* 添加事件监听(防止框架回调API的改变,增加扩展性)
*/
public interface DisposeDataListener {
/**
* 请求成功回调事件处理
*/
public void onSuccess (Object responseObj);
/**
* 请求失败回调事件处理
*/
public void onFailure (Object reasonObj);
}
DisposeDataHandle类
将回调监听对象和要转化的字节码进行封装
/**
* Created by Administrator on 2017/7/23.
* 将回调监听对象和要转化的字节码进行封装
*/
public class DisposeDataHandle {
public DisposeDataListener mListener = null ;
public Class<?> mClass = null ;
public DisposeDataHandle (DisposeDataListener mListener) {
this .mListener = mListener;
}
public DisposeDataHandle (Class<?> mClass, DisposeDataListener mListener) {
this .mClass = mClass;
this .mListener = mListener;
}
}
CommonJsonCallback类
处理json的回调响应,返回callBack对象
import android.os.Handler;
import android.os.Looper;
import com.yingyuliuliwan.liuliwansdk.adutil.ResponseEntityToModule;
import com.yingyuliuliwan.liuliwansdk.okhttps.exception.OkHttpException;
import com.yingyuliuliwan.liuliwansdk.okhttps.listener.DisposeDataHandle;
import com.yingyuliuliwan.liuliwansdk.okhttps.listener.DisposeDataListener;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.Response;
/**
* Created by xiaoxu on 2017/7/23.
*/
public class CommonJsonCallback implements Callback {
protected final String RESULT_CODE = "ecode" ;
protected final int RESULT_CODE_VALUE = 0 ;
protected final String ERROR_MSG = "emsg" ;
protected final String EMPTY_MSG = "" ;
protected final String COOKIE_STORE = "Set-Cookie" ;
/**
* 自定义异常类型
*/
protected final int NETWORK_ERROR = -1 ;
protected final int JSON_ERROR = -2 ;
protected final int OTHER_ERROR = -3 ;
/**
* 将其它线程的数据转发到UI线程
*/
private Handler mDeliveryHandler;
private DisposeDataListener mListener;
private Class<?> mClass;
public CommonJsonCallback (DisposeDataHandle handle) {
this .mListener = handle.mListener;
this .mClass = handle.mClass;
this .mDeliveryHandler = new Handler(Looper.getMainLooper());
}
@Override
public void onFailure (final Call call, final IOException ioexception) {
/**
* 此时还在非UI线程,因此要转发
*/
mDeliveryHandler.post(new Runnable() {
@Override
public void run () {
mListener.onFailure(new OkHttpException(NETWORK_ERROR, ioexception));
}
});
}
@Override
public void onResponse (final Call call, final Response response) throws IOException {
final String result = response.body().string();
final ArrayList<String> cookieLists = handleCookie(response.headers());
mDeliveryHandler.post(new Runnable() {
@Override
public void run () {
handleResponse(result);
/**后续升级准备
* handle the cookie
*/
}
});
}
private void handleResponse (Object responseObj) {
if (responseObj == null || responseObj.toString().trim().equals("" )) {
mListener.onFailure(new OkHttpException(NETWORK_ERROR, EMPTY_MSG));
return ;
}
try {
JSONObject result = new JSONObject(responseObj.toString());
if (result.has(RESULT_CODE)){
if (result.getInt(RESULT_CODE)==RESULT_CODE_VALUE){
if (mClass == null ) {
mListener.onSuccess(result);
} else {
Object obj = ResponseEntityToModule.parseJsonObjectToModule(result, mClass);
if (obj != null ) {
mListener.onSuccess(obj);
} else {
mListener.onFailure(new OkHttpException(JSON_ERROR, EMPTY_MSG));
}
}
}
}
} catch (Exception e) {
mListener.onFailure(new OkHttpException(OTHER_ERROR, e.getMessage()));
e.printStackTrace();
}
}
}
ResponseEntityToModule类
将json对象转化为实体类对象(也可以使用第三方库)
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import io.realm.RealmList;
import io.realm.RealmModel;
import io.realm.RealmObject;
public class ResponseEntityToModule {
public static Object parseJsonToModule(String jsonContent, Class<?> clazz) {
Object moduleObj = null ;
try {
JSONObject jsonObj = new JSONObject(jsonContent);
moduleObj = parseJsonObjectToModule(jsonObj, clazz);
} catch (JSONException e) {
e.printStackTrace();
}
return moduleObj;
}
public static Object parseJsonObjectToModule(JSONObject jsonObj, Class<?> clazz) {
Object moduleObj = null ;
try {
moduleObj = (Object) clazz.newInstance();
setFieldValue(moduleObj, jsonObj, clazz);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return moduleObj;
}
public static RealmObject parseJsonObjectToRealmModel(JSONObject jsonObj, Class<?> clazz) {
RealmObject moduleObj = null ;
try {
moduleObj = (RealmObject) clazz.newInstance();
setFieldValue(moduleObj, jsonObj, clazz);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return moduleObj;
}
private static void setFieldValue(Object moduleObj, JSONObject jsonObj, Class<?> clazz)
throws IllegalArgumentException, IllegalAccessException, JSONException, InstantiationException {
if (clazz.getSuperclass() != null ) {
setFieldValue(moduleObj, jsonObj, clazz.getSuperclass());
}
Field[] fields = clazz.getDeclaredFields();
Class<?> cls;
String name;
for (Field f : fields) {
f.setAccessible(true );
cls = f.getType();
name = f.getName();
if (!jsonObj.has(name) || jsonObj.isNull(name)) {
continue ;
}
if (cls.isPrimitive() || isWrappedPrimitive(cls))
{
setPrimitiveFieldValue(f, moduleObj, jsonObj.get (name));
} else {
if (cls.isAssignableFrom(String.class )) {
f.set (moduleObj, String.valueOf(jsonObj.get (name)));
} else if (cls.isAssignableFrom(ArrayList.class )) {
parseJsonArrayToList(f, name, moduleObj, jsonObj);
}
else if (cls.isAssignableFrom(RealmList.class )) {
parseJsonArrayToRealmList(f, name, moduleObj, jsonObj);
} else {
Object obj = parseJsonObjectToModule(jsonObj.getJSONObject(name), cls.newInstance().getClass());
f.set (moduleObj, obj);
}
}
}
}
private static RealmList<RealmObject> parseJsonArrayToRealmList(Field field, String fieldName, Object moduleObj,
JSONObject jsonObj) throws JSONException, IllegalArgumentException, IllegalAccessException {
RealmList<RealmObject> objList = new RealmList<>();
Type fc = field.getGenericType();
if (fc instanceof ParameterizedType)
{
ParameterizedType pt = (ParameterizedType) fc;
if (pt.getActualTypeArguments()[0 ] instanceof Class)
{
Class<?> clss = (Class<?>) pt.getActualTypeArguments()[0 ];
if (jsonObj.get (fieldName) instanceof JSONArray) {
JSONArray array = jsonObj.getJSONArray(fieldName);
for (int i = 0 ; i < array.length(); i++) {
if (array.get (i) instanceof JSONObject) {
objList.add(parseJsonObjectToRealmModel(array.getJSONObject(i), clss));
} else {
if (clss.isAssignableFrom(array.get (i).getClass())) {
objList.add((RealmObject) array.get (i));
}
}
}
}
field.set (moduleObj, objList);
}
}
return objList;
}
private static ArrayList<Object> parseJsonArrayToList(Field field, String fieldName, Object moduleObj,
JSONObject jsonObj) throws JSONException, IllegalArgumentException, IllegalAccessException {
ArrayList<Object> objList = new ArrayList<Object>();
Type fc = field.getGenericType();
if (fc instanceof ParameterizedType)
{
ParameterizedType pt = (ParameterizedType) fc;
if (pt.getActualTypeArguments()[0 ] instanceof Class)
{
Class<?> clss = (Class<?>) pt.getActualTypeArguments()[0 ];
if (jsonObj.get (fieldName) instanceof JSONArray) {
JSONArray array = jsonObj.getJSONArray(fieldName);
for (int i = 0 ; i < array.length(); i++) {
if (array.get (i) instanceof JSONObject) {
objList.add(parseJsonObjectToModule(array.getJSONObject(i), clss));
} else {
if (clss.isAssignableFrom(array.get (i).getClass())) {
objList.add(array.get (i));
}
}
}
}
field.set (moduleObj, objList);
}
}
return objList;
}
private static void setPrimitiveFieldValue(Field field, Object moduleObj, Object jsonObj)
throws IllegalArgumentException, IllegalAccessException {
if (field.getType().isAssignableFrom(jsonObj.getClass())) {
field.set (moduleObj, jsonObj);
} else {
field.set (moduleObj, makeTypeSafeValue(field.getType(), jsonObj.toString()));
}
}
private static final Object makeTypeSafeValue(Class<?> type, String value) throws NumberFormatException,
IllegalArgumentException {
if (int.class == type || Integer.class == type) {
return Integer.parseInt(value);
} else if (long.class == type || Long.class == type) {
return Long.parseLong(value);
} else if (short.class == type || Short.class == type) {
return Short.parseShort(value);
} else if (char.class == type || Character.class == type) {
return value.charAt(0 );
} else if (byte.class == type || Byte.class == type) {
return Byte.valueOf(value);
} else if (float.class == type || Float.class == type) {
return Float.parseFloat(value);
} else if (double.class == type || Double.class == type) {
return Double.parseDouble(value);
} else if (boolean.class == type || Boolean.class == type) {
return Boolean.valueOf(value);
} else {
return value;
}
}
private static boolean isWrappedPrimitive(Class<?> type) {
if (type.getName().equals(Boolean.class .getName()) || type.getName().equals(Byte.class .getName())
|| type.getName().equals(Character.class .getName()) || type.getName().equals(Short.class .getName())
|| type.getName().equals(Integer.class .getName()) || type.getName().equals(Long.class .getName())
|| type.getName().equals(Float.class .getName()) || type.getName().equals(Double.class .getName())) {
return true ;
}
return false ;
}
}