Android Volley 之自定义Request


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

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


一些简单的用法实例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. RequestQueue newRequestQueue = Volley.newRequestQueue(MainActivity.this);  
  2.     StringRequest stringRequest = new StringRequest("http://www.baidu.com"new Response.Listener<String>()  
  3.     {  
  4.   
  5.         @Override  
  6.         public void onResponse(String response)  
  7.         {  
  8.             Log.e("TAG", response);  
  9.   
  10.         }  
  11.     }, new Response.ErrorListener()  
  12.     {  
  13.         @Override  
  14.         public void onErrorResponse(VolleyError error)  
  15.         {  
  16.             Log.e("TAG", error.getMessage(), error);  
  17.         }  
  18.     });  
  19.   
  20.     JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html",  
  21.             nullnew Response.Listener<JSONObject>()  
  22.             {  
  23.   
  24.                 @Override  
  25.                 public void onResponse(JSONObject response)  
  26.                 {  
  27.                     Log.e("TAG", response.toString());  
  28.                 }  
  29.             }, new Response.ErrorListener()  
  30.             {  
  31.   
  32.                 @Override  
  33.                 public void onErrorResponse(VolleyError error)  
  34.                 {  
  35.                     Log.e("TAG", error.getMessage(), error);  
  36.                 }  
  37.             });  
  38.   
  39.     ImageRequest imageRequest = new ImageRequest("http://imgt6.bdstatic.com/it/u=2,887966933&fm=19&gp=0.jpg",  
  40.             new Response.Listener<Bitmap>()  
  41.             {  
  42.   
  43.                 @Override  
  44.                 public void onResponse(Bitmap response)  
  45.                 {  
  46.                     mImageView.setImageBitmap(response);  
  47.                 }  
  48.             }, 00, Config.RGB_565, null);  
  49.   
  50.     newRequestQueue.add(stringRequest);  
  51.     newRequestQueue.add(imageRequest);  
  52.     newRequestQueue.add(jsonObjectRequest);  

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


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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public StringRequest(int method, String url, Listener<String> listener,  
  2.           ErrorListener errorListener) {  
  3.       super(method, url, errorListener);  
  4.       mListener = listener;  
  5.   }  

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2.   protected Response<String> parseNetworkResponse(NetworkResponse response) {  
  3.       String parsed;  
  4.       try {  
  5.           parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));  
  6.       } catch (UnsupportedEncodingException e) {  
  7.           parsed = new String(response.data);  
  8.       }  
  9.       return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));  
  10.   }  

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


下面直接上例子:

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

1、对象:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.zhy.velloydemo;  
  2.   
  3. public class User  
  4. {  
  5.     private String name;  
  6.     private int age;  
  7.   
  8.     public String getName()  
  9.     {  
  10.         return name;  
  11.     }  
  12.   
  13.     public void setName(String name)  
  14.     {  
  15.         this.name = name;  
  16.     }  
  17.   
  18.     public int getAge()  
  19.     {  
  20.         return age;  
  21.     }  
  22.   
  23.     public void setAge(int age)  
  24.     {  
  25.         this.age = age;  
  26.     }  
  27.   
  28.     @Override  
  29.     public String toString()  
  30.     {  
  31.         return "User [name=" + name + ", age=" + age + "]";  
  32.     }  
  33.   
  34.       
  35. }  

2、自定义的Request

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.zhy.velloydemo;  
  2.   
  3. import java.io.UnsupportedEncodingException;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import com.android.volley.AuthFailureError;  
  8. import com.android.volley.NetworkResponse;  
  9. import com.android.volley.ParseError;  
  10. import com.android.volley.Request;  
  11. import com.android.volley.Response;  
  12. import com.android.volley.Response.ErrorListener;  
  13. import com.android.volley.Response.Listener;  
  14. import com.android.volley.toolbox.HttpHeaderParser;  
  15. import com.google.gson.Gson;  
  16. import com.google.gson.JsonSyntaxException;  
  17.   
  18. public class JsonRequestWithAuth<T> extends Request<T>  
  19. {  
  20.     private final Gson gson = new Gson();  
  21.     private final Class<T> clazz;  
  22.     private final Listener<T> listener;  
  23.   
  24.     private static Map<String, String> mHeader = new HashMap<String, String>();  
  25.     /** 
  26.      * 设置访问自己服务器时必须传递的参数,密钥等 
  27.      */  
  28.     static  
  29.     {  
  30.         mHeader.put("APP-Key""LBS-AAA");  
  31.         mHeader.put("APP-Secret""ad12msa234das232in");  
  32.     }  
  33.   
  34.     /** 
  35.      * @param url 
  36.      * @param clazz 
  37.      *            我们最终的转化类型 
  38.      * @param headers 
  39.      *            请求附带的头信息 
  40.      * @param listener 
  41.      * @param appendHeader 
  42.      *            附加头数据 
  43.      * @param errorListener 
  44.      */  
  45.     public JsonRequestWithAuth(String url, Class<T> clazz, Listener<T> listener, Map<String, String> appendHeader,  
  46.             ErrorListener errorListener)  
  47.     {  
  48.         super(Method.GET, url, errorListener);  
  49.         this.clazz = clazz;  
  50.         this.listener = listener;  
  51.         mHeader.putAll(appendHeader);  
  52.     }  
  53.   
  54.     @Override  
  55.     public Map<String, String> getHeaders() throws AuthFailureError  
  56.     {  
  57.         // 默认返回 return Collections.emptyMap();  
  58.         return mHeader;  
  59.     }  
  60.   
  61.     @Override  
  62.     protected void deliverResponse(T response)  
  63.     {  
  64.         listener.onResponse(response);  
  65.     }  
  66.   
  67.     @Override  
  68.     protected Response<T> parseNetworkResponse(NetworkResponse response)  
  69.     {  
  70.         try  
  71.         {  
  72.             /** 
  73.              * 得到返回的数据 
  74.              */  
  75.             String jsonStr = new String(response.data, HttpHeaderParser.parseCharset(response.headers));  
  76.             /** 
  77.              * 转化成对象 
  78.              */  
  79.             return Response.success(gson.fromJson(jsonStr, clazz), HttpHeaderParser.parseCacheHeaders(response));  
  80.         } catch (UnsupportedEncodingException e)  
  81.         {  
  82.             return Response.error(new ParseError(e));  
  83.         } catch (JsonSyntaxException e)  
  84.         {  
  85.             return Response.error(new ParseError(e));  
  86.         }  
  87.     }  
  88. }  

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

3、服务器代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.zhy.servelt;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.ServletOutputStream;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11.   
  12. public class TestServlet extends HttpServlet  
  13. {  
  14.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  15.             throws ServletException, IOException  
  16.     {  
  17.         this.doPost(request, response);  
  18.     }  
  19.   
  20.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  21.             throws ServletException, IOException  
  22.     {  
  23.         request.setCharacterEncoding("utf-8");  
  24.           
  25.         String appKey = request.getHeader("APP-Key");  
  26.         String appSecret = request.getHeader("APP-Secret");  
  27.   
  28.         String username = request.getHeader("username");  
  29.         String password = request.getHeader("password");  
  30.   
  31.         if ("admin".equals(username) && "123".equals(password))  
  32.         {  
  33.             response.setContentType("text/plain;charset=utf-8");  
  34.             PrintWriter out = response.getWriter();  
  35.             out.print("{\"name\":\"鸿洋\",\"age\":32}");  
  36.             out.flush();  
  37.               
  38.         }  
  39.   
  40.     }  
  41.   
  42. }  

4、测试代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Map<String, String> appendHeader = new HashMap<String, String>();  
  2.         appendHeader.put("username""admin");  
  3.         appendHeader.put("password""123");  
  4.   
  5.         String url = "http://172.27.35.1:8080/webTest/TestServlet";  
  6.         JsonRequestWithAuth<User> userRequest = new JsonRequestWithAuth<User>(url, User.classnew Listener<User>()  
  7.         {  
  8.             @Override  
  9.             public void onResponse(User response)  
  10.             {  
  11.                 Log.e("TAG", response.toString());  
  12.             }  
  13.         }, appendHeader, null);  
  14.   
  15.         newRequestQueue.add(userRequest);  
  16.           



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

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

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

最后补充一下:

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

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


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值