您的位置:首页 > 产品设计 > UI/UE

Android Volley 之自定义Request

2016-05-06 15:47 489 查看

转载标明出处:http://blog.csdn.net/lmj623565791/article/details/24589837

今天群里一哥们需要自定义Volley的Request的例子,于是产生了这篇博客。关于Volley的介绍就不多说了,网上例子特别多。

Volley的所有的请求的超类型是Resuest,类结构如下图,所有我们常用的请求都是这个类的子类,那么我们自定义View肯定也是基于这个类的。



一些简单的用法实例:

[java]
view plain
copy





RequestQueue newRequestQueue = Volley.newRequestQueue(MainActivity.this);  
    StringRequest stringRequest = new StringRequest("http://www.baidu.com", new Response.Listener<String>()  
    {  
  
        @Override  
        public void onResponse(String response)  
        {  
            Log.e("TAG", response);  
  
        }  
    }, new Response.ErrorListener()  
    {  
        @Override  
        public void onErrorResponse(VolleyError error)  
        {  
            Log.e("TAG", error.getMessage(), error);  
        }  
    });  
  
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html",  
            null, new Response.Listener<JSONObject>()  
            {  
  
                @Override  
                public void onResponse(JSONObject response)  
                {  
                    Log.e("TAG", response.toString());  
                }  
            }, new Response.ErrorListener()  
            {  
  
                @Override  
                public void onErrorResponse(VolleyError error)  
                {  
                    Log.e("TAG", error.getMessage(), error);  
                }  
            });  
  
    ImageRequest imageRequest = new ImageRequest("http://imgt6.bdstatic.com/it/u=2,887966933&fm=19&gp=0.jpg",  
            new Response.Listener<Bitmap>()  
            {  
  
                @Override  
                public void onResponse(Bitmap response)  
                {  
                    mImageView.setImageBitmap(response);  
                }  
            }, 0, 0, Config.RGB_565, null);  
  
    newRequestQueue.add(stringRequest);  
    newRequestQueue.add(imageRequest);  
    newRequestQueue.add(jsonObjectRequest);  

基本都是new一个请求,加入请求队列就行了。

好了,下面进入正题,如何自定义自己的Request,其实很简单,咱们打开StringRequest的源码:

[java]
view plain
copy





public StringRequest(int method, String url, Listener<String> listener,  
          ErrorListener errorListener) {  
      super(method, url, errorListener);  
      mListener = listener;  
  }  

构造方法中指明访问的url,method,和回调的接口,毕竟我们要处理数据么。

[java]
view plain
copy





@Override  
  protected Response<String> parseNetworkResponse(NetworkResponse response) {  
      String parsed;  
      try {  
          parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));  
      } catch (UnsupportedEncodingException e) {  
          parsed = new String(response.data);  
      }  
      return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));  
  }  

最终给我们返回的数据就是parsed,比如我们返回的是json字符串,我们就可以在这添几行代码,把字符串转换成对象返回。(很重要的是,返回类型是咱们声明Request的时候定的,是个泛型)。

下面直接上例子:

例子是,通过客户端访问服务器,服务器对客户端进行身份校验后,返回JSON字符串,客户端直接拿到对象。

1、对象:

[java]
view plain
copy





package com.zhy.velloydemo;  
  
public class User  
{  
    private String name;  
    private int age;  
  
    public String getName()  
    {  
        return name;  
    }  
  
    public void setName(String name)  
    {  
        this.name = name;  
    }  
  
    public int getAge()  
    {  
        return age;  
    }  
  
    public void setAge(int age)  
    {  
        this.age = age;  
    }  
  
    @Override  
    public String toString()  
    {  
        return "User [name=" + name + ", age=" + age + "]";  
    }  
  
      
}  

2、自定义的Request

[java]
view plain
copy





package com.zhy.velloydemo;  
  
import java.io.UnsupportedEncodingException;  
import java.util.HashMap;  
import java.util.Map;  
  
import com.android.volley.AuthFailureError;  
import com.android.volley.NetworkResponse;  
import com.android.volley.ParseError;  
import com.android.volley.Request;  
import com.android.volley.Response;  
import com.android.volley.Response.ErrorListener;  
import com.android.volley.Response.Listener;  
import com.android.volley.toolbox.HttpHeaderParser;  
import com.google.gson.Gson;  
import com.google.gson.JsonSyntaxException;  
  
public class JsonRequestWithAuth<T> extends Request<T>  
{  
    private final Gson gson = new Gson();  
    private final Class<T> clazz;  
    private final Listener<T> listener;  
  
    private static Map<String, String> mHeader = new HashMap<String, String>();  
    /** 
     * 设置访问自己服务器时必须传递的参数,密钥等 
     */  
    static  
    {  
        mHeader.put("APP-Key", "LBS-AAA");  
        mHeader.put("APP-Secret", "ad12msa234das232in");  
    }  
  
    /** 
     * @param url 
     * @param clazz 
     *            我们最终的转化类型 
     * @param headers 
     *            请求附带的头信息 
     * @param listener 
     * @param appendHeader 
     *            附加头数据 
     * @param errorListener 
     */  
    public JsonRequestWithAuth(String url, Class<T> clazz, Listener<T> listener, Map<String, String> appendHeader,  
            ErrorListener errorListener)  
    {  
        super(Method.GET, url, errorListener);  
        this.clazz = clazz;  
        this.listener = listener;  
        mHeader.putAll(appendHeader);  
    }  
  
    @Override  
    public Map<String, String> getHeaders() throws AuthFailureError  
    {  
        // 默认返回 return Collections.emptyMap();  
        return mHeader;  
    }  
  
    @Override  
    protected void deliverResponse(T response)  
    {  
        listener.onResponse(response);  
    }  
  
    @Override  
    protected Response<T> parseNetworkResponse(NetworkResponse response)  
    {  
        try  
        {  
            /** 
             * 得到返回的数据 
             */  
            String jsonStr = new String(response.data, HttpHeaderParser.parseCharset(response.headers));  
            /** 
             * 转化成对象 
             */  
            return Response.success(gson.fromJson(jsonStr, clazz), HttpHeaderParser.parseCacheHeaders(response));  
        } catch (UnsupportedEncodingException e)  
        {  
            return Response.error(new ParseError(e));  
        } catch (JsonSyntaxException e)  
        {  
            return Response.error(new ParseError(e));  
        }  
    }  
}  

这里说一下,我在Header中放置了APP-key等数据,也就是说只要我们这个请求发的都会有这几个值,大家开发app时肯定有很多请求参数是需要每次都发往服务器校验的,可以在这里设置。
3、服务器代码:

[java]
view plain
copy





package com.zhy.servelt;  
  
import java.io.IOException;  
import java.io.PrintWriter;  
  
import javax.servlet.ServletException;  
import javax.servlet.ServletOutputStream;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
  
public class TestServlet extends HttpServlet  
{  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException  
    {  
        this.doPost(request, response);  
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException  
    {  
        request.setCharacterEncoding("utf-8");  
          
        String appKey = request.getHeader("APP-Key");  
        String appSecret = request.getHeader("APP-Secret");  
  
        String username = request.getHeader("username");  
        String password = request.getHeader("password");  
  
        if ("admin".equals(username) && "123".equals(password))  
        {  
            response.setContentType("text/plain;charset=utf-8");  
            PrintWriter out = response.getWriter();  
            out.print("{\"name\":\"鸿洋\",\"age\":32}");  
            out.flush();  
              
        }  
  
    }  
  
}  

4、测试代码:

[java]
view plain
copy





Map<String, String> appendHeader = new HashMap<String, String>();  
        appendHeader.put("username", "admin");  
        appendHeader.put("password", "123");  
  
        String url = "http://172.27.35.1:8080/webTest/TestServlet";  
        JsonRequestWithAuth<User> userRequest = new JsonRequestWithAuth<User>(url, User.class, new Listener<User>()  
        {  
            @Override  
            public void onResponse(User response)  
            {  
                Log.e("TAG", response.toString());  
            }  
        }, appendHeader, null);  
  
        newRequestQueue.add(userRequest);  
          



可以看到我们使用自定义请求实现了我们上述的需求,这里还要说一下,这个例子有两个目的:

1、自定义Request其实很简单,如果不需要Header直接不用复写getHeader那个方法。

2、我们可以利用Header传递一些固定的参数,这比对安全比较高的系统,每次拼一堆xml去服务器,代码能简洁很多,当然了,注意信息安全。

最后补充一下:

哥们问这句什么意思:HttpHeaderParser.parseCharset(response.headers)其实就是获取我们的返回流的编码,也就是我上面服务器设置的utf-8

对于请求的Header和响应Header理解,随便打开个网站,使用浏览器的工具查看一下,每个请求都会包含这两个Header数据。

好了,就到这里~各位留个言、赞一个算对我们的支持~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Volley 自定义Request