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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值