您的位置:首页 > 理论基础 > 计算机网络

网络请求框架-基于Volley(一)

2016-12-07 15:39 309 查看
直接参考volley的JsonRequest 和 JsonObjectRequest的代码

BeanRequest.java

BeanRequest继承了Request,并且使用泛型,利用反射机制获取泛型的Type,使用fastjson将接口返回的数据(String型)转换为我们需要的Bean。泛型继承了BaseBean,BaseBean包含code和msg,BaseBean保存接口返回的通有数据,如果有其他的可以自行添加。这样就实现了直接返回需要的实体类的数据类型。

import com.alibaba.fastjson.JSON;
import com.android.volley.AuthFailureError;
import com.android.volley.Cache;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.hongxue.volley.bean.BaseBean;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

public class BeanRequest<T extends BaseBean> extends Request<T> {

protected static final String PROTOCOL_CHARSET = "utf-8";

private final SuccessListener<T> mSuccessListener;
private Map<String, String> mPostParamMap;

public static abstract class SuccessListener<T> {
private final Type type;

protected SuccessListener() {
//利用反射机制获取泛型的Type
Type superClass = getClass().getGenericSuperclass();
type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}

public Type getType() {
return type;
}

public abstract void onResponse(T response);
}

public BeanRequest(int method, String url, Map<String, Object> postParamMap, SuccessListener<T> successListener, Response.ErrorListener errorListener) {
super(method, url, errorListener);

mSuccessListener = successListener;

if (postParamMap != null) {//postParamMap不为空用的是post方法
mPostParamMap = new HashMap<>(postParamMap.size());
for (Map.Entry<String, Object> entry : postParamMap.entrySet()) {
mPostParamMap.put(entry.getKey(), String.valueOf(entry.getValue()));
}
}

}

/**
* post方式使用getParams()将参数交给父类处理
*/
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return mPostParamMap;
}

@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));

Type type = mSuccessListener.getType();
T bean = JSON.parseObject(jsonString, type);//这里使用fastjson直接将String转换成Bean
Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
return Response.success(bean, entry);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return Response.error(new ParseError(e));
}
}

@Override
protected void deliverResponse(T response) {
mSuccessListener.onResponse(response);//回调
}
}


BaseBean:一般网络请求都会返回code和msg

public class BaseBean {

private String code;
private String msg;

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}
}


封装自己的HttpClient

public class HxHttpClient {

private static RequestQueue requestQueue;
private final Context context;

private HxHttpClient(Context context) {
this.context = context;
}

public synchronized static HxHttpClient newInstance(Context context) {
if (requestQueue == null) {
HTTPSTrustManager.allowAllSSL();//跳过https的验证,如果用的http请求可以忽略
requestQueue = Volley.newRequestQueue(context.getApplicationContext());
}
return new HxHttpClient(context);
}

public RequestQueue getRequestQueue() {
return requestQueue;
}

public <T extends BaseBean> BeanRequest<T> request(BaseApi api, BeanRequest.SuccessListener<T> successListener, Response.ErrorListener errorListener) {
String url = api.getUrl();
TreeMap<String, Object> params = api.getParams();

if (api.requestMethod() == BaseApi.Method.POST) {
return post(url, params, successListener, errorListener);
} else {
if (!params.isEmpty()) {
url += "?" + mapToQueryString(params);
}
return get(url, successListener, errorListener);
}
}

public <T extends BaseBean> BeanRequest<T> post(String url, Map<String, Object> postParamMap, BeanRequest.SuccessListener<T> successListener, Response.ErrorListener errorListener) {
BeanRequest<T> request = new BeanRequest<>(Request.Method.POST, url, postParamMap, successListener, errorHandler(errorListener));
addRequest(request);
return request;
}

public <T extends BaseBean> BeanRequest<T> get(String url, BeanRequest.SuccessListener<T> successListener, Response.ErrorListener errorListener) {
BeanRequest<T> request = new BeanRequest<T>(Request.Method.GET, url, null, successListener, errorHandler(errorListener));
addRequest(request);
return request;
}

private <T extends BaseBean> void addRequest(BeanRequest<T> request) {
requestQueue.add(request);
}

public Response.ErrorListener errorHandler(final Response.ErrorListener errorListener) {
return new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error = new VolleyError("亲,您的网络不太顺畅喔~", error);

if (errorListener != null) {
errorListener.onErrorResponse(error);
}

}
};
}

/**
* 参数拼接
*/
private String mapToQueryString(Map<String, Object> params) {
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (entry.getValue() == null || entry.getValue() instanceof File)
continue;
encodedParams.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"));
encodedParams.append('&');
}
return encodedParams.toString();
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: UTF-8", uee);
}
}

}


BaseApi

import com.hongxue.volley.constants.HttpConstant;
import java.lang.reflect.Field;
import java.util.TreeMap;

public abstract class BaseApi {

public enum Method {
GET,
POST,
}

protected abstract String getPath();

public abstract Method requestMethod();

public String getUrl() {
return HttpConstant.API_URL + getPath();
}

/**
* 获得请求接口添加的参数
*/
public TreeMap<String, Object> getParams() {
TreeMap<String, Object> params = new TreeMap<String, Object>();
Class clazz = getClass();
Field[] field = clazz.getDeclaredFields();//getDeclaredFields()返回Class中所有的字段,包括私有字段
//这里获取到的是GetImageListInfoApi的type,具体看GetImageListInfoApi.java
try {
for (Field f : field) {
f.setAccessible(true);
if (f.get(this) != null) {
params.put(f.getName(), f.get(this));
}
}
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}

return params;
}

}


GetImageInfoApi

public class GetImageListInfoApi extends BaseApi{

private String type;//请求接口需要传递的参数

@Override
public Method requestMethod() {
return Method.POST;
}

@Override
protected String getPath() {
return "api/接口名";
}

public void setType(String type) {
this.type = type;
}
}


获取图片信息

private void getImageListInfo() {
GetImageListInfoApi api = new GetImageListInfoApi();
api.setType("1");

HxHttpClient.newInstance(MainActivity.this).request(api,

new BeanRequest.SuccessListener<ImageListBean >() {

@Override
public void onResponse(ImageListBean response) {
//直接返回了ImageListBean
ArrayList<ImageBean> list = response.getDataList();

}
}, new Response.ErrorListener() {

@Override
public void onErrorResponse(VolleyError error) {

}
}
);
}


ImageListBean

public class ImageListBean extends BaseBean {

ArrayList<ImageBean> dataList;

public ArrayList<ImageBean> getDataList() {
return dataList;
}

public void setDataList(ArrayList<ImageBean> dataList) {
this.dataList = dataList;
}
}


ImageBean

public class ImageBean {

public String name;//图片名
public String imageUrl;//图片地址

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getImageUrl() {
return imageUrl;
}

public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}

}


总结:总的来说就是使用反射机制和fastjson实现了返回我们需要的实体类类型
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: