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

来源:互联网 发布:泉山区淘宝 编辑:程序博客网 时间:2024/06/05 03:00

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

0 0