Android Volley 之自定义Request

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

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

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


一些简单的用法实例:

	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的源码:

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

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

  @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、对象:

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

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、服务器代码:

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、测试代码:

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数据。




好了,就到这里~各位留个言、赞一个算对我们的支持~










版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2014-04-27 16:16  dingxiaoyue  阅读(210)  评论(0编辑  收藏  举报