Volley 简单使用(二) JsonRequest以及自定义Request

目前大部分请求返回的数据都是JSON格式,为了方便解析,Volley还提供了JsonRequest,其中包括JsonObjectRequest和JsonArrayRequest。
使用方法和StringRequest基本相同,只不过返回的数据为JSONObject或者JSONArray,大大增加了便利性。
如果JSONObject和JSONArray还不能满足需求的话,也可以通过继承Request类的方式自定义Gson或者FastJson的请求。

JsonRequest基本使用

获取RequestQueue

1
RequestQueue mQueue = Volley.newRequestQueue(mContext);

JsonObjectRequest

首先和StringRequest类似,JsonObjectRequest返回的是JSONObject

1
2
3
private Response.Listener<JSONObject> mJsonObjectResultListener = response -> {
Log.i("JsonResult", response.toString());
};

创建请求,其中mErrorListener和StringRequest完全一样,根据需求随便写

1
2
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(URL_GET, null, mJsonObjectResultListener, mErrorListener);
mQueue.add(jsonObjectRequest);

由于返回的数据直接就是JSONObject,就可以直接对其进行解析,和StringRequest对比就是省去了JSONString转JSON的过程

JsonArrayRequest

由于基本没有区别,直接上代码,返回数据类型为JSONArray

1
2
3
private Response.Listener<JSONArray> mJsonArrayResultListener = response -> {
String s = response.toString();
};

创建请求

1
2
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(URL_GET, mJsonArrayResultListener, mErrorListener);
mQueue.add(jsonArrayRequest);

进行JsonArrayRequest的时候必须保证返回的数据直接就是JSONArray类型,根节点不能包含其他数据,否则会报数据解析错误

自定义Request进行JSON数据获取

自定义Request最快方法就是抄袭,查看StringRequest或者JsonRequest就可以发现,Request的封装非常简单,而且JsonObjectRequest或者JsonArrayRequest和StringRequest区别就在于,前两个是把StringRequest得到的String数据转换成了JSON。
也正因如此,进行JsonArrayRequest的时候,如果返回数据不是JSONArray的情况下会报数据解析错误。
JsonObjectRequest解析部分代码:

1
2
3
4
5
6
7
8
9
10
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString =new String(response.data, HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
return Response.success(new JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}

Volley+Gson进行数据解析

使用Gson进行数据解析,首先就需要添加Gson依赖

1
implementation 'com.google.code.gson:gson:2.8.5'

自定义GsonRequest,继承自Request,唯一需要做的就是将获取到的数据通过Gson进行转换

1
2
3
4
5
6
7
8
9
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
T result = mGson.fromJson(jsonString, mClazz);
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}

完整示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class GsonRequest<T> extends Request<T> {
private static final String PROTOCOL_CHARSET = "utf-8";
private Response.Listener<T> mListener;
private Class<T> mClazz;
private Gson mGson;

public GsonRequest(String url, Class<T> mClazz, Response.Listener<T> mListener, Response.ErrorListener errorListener) {
this(Method.GET, url, mClazz, mListener, errorListener);
}

public GsonRequest(int method, String url, Class<T> mClazz, Response.Listener<T> mListener, @Nullable Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = mListener;
this.mClazz = mClazz;
mGson = new Gson();

}

@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
T result = mGson.fromJson(jsonString, mClazz);
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}

@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}

parseNetworkResponse返回需要解析处理数据,处理的结果将返回给deliverResponse
deliverResponse返回解析完的数据,需要将这个结果通过Response.Listener返回给用户
由于数据结果是不固定的所以POJO是不固定的,所以依然使用泛型

调用

1
2
3
4
5
6
// 设置返回监听及约定返回类型
private Response.Listener<JsonResult> mGsonResultListener = response -> {};

// 调用
GsonRequest<JsonResult> gsonRequest = new GsonRequest<>(URL_GET, JsonResult.class, mGsonResultListener, mErrorListener);
mQueue.add(gsonRequest);

调用方式和Volley提供的两个方式基本一致

Volley+FastJson进行数据解析

引入FastJson依赖

1
implementation 'com.alibaba:fastjson:1.2.56'

由于代码和Gson基本一致,直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class FastJsonRequest<T> extends Request<T> {
private static final String PROTOCOL_CHARSET = "utf-8";
private Response.Listener<T> mListener;
private Class<T> mClazz;

public FastJsonRequest(String url, Class<T> clazz, Response.Listener<T> mListener, Response.ErrorListener mErrorListener) {
this(Method.GET, url, clazz, mListener, mErrorListener);
}

public FastJsonRequest(int method, String url, Class<T> clazz, Response.Listener<T> mListener, @Nullable Response.ErrorListener mErrorListener) {
super(method, url, mErrorListener);
this.mListener = mListener;
this.mClazz = clazz;
}

@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
T result = JSON.parseObject(jsonString, mClazz);
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}

@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}

调用

1
2
FastJsonRequest<JsonResult> fastJsonRequest = new FastJsonRequest<>(URL_GET, JsonResult.class, mGsonResultListener, mErrorListener);
mQueue.add(fastJsonRequest);