直接参考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实现了返回我们需要的实体类类型