咸鱼

咸鱼是以盐腌渍后,晒干的鱼

0%

写一个Volley自定义Request

参考:request-custom

在Android中,使用Volley来请求JSON数据,Volley自带 StringRequest JsonObjectRequest JsonArrayRequest JsonRequest

GET示例

自定义Request,就是在Request中使用Gson把数据处理为对象,返回给调用者。示例 GsonRequestSample.java (GET Request):

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//代码来自:https://developer.android.google.cn/training/volley/request-custom
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.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import java.io.UnsupportedEncodingException;
import java.util.Map;

public class GsonRequestSample<T> extends Request<T> {

private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Response.Listener<T> listener;


/**
* Make a GET request and return a parsed object from JSON.
*
* @param url URL of the request to make
* @param clazz Relevant class object, for Gson's reflection
* @param headers Map of request headers
*/

public GsonRequestSample(String url, Class<T> clazz, Map<String, String> headers,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}

@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}

修改为POST

现在,把以上的示例改为用户登录接口,使其支持 POST Request,参数已JSON的格式发送,响应为JSON格式数据,转为本地Bean类。

请求体:

1
2
3
4
5
6
7
8
POST /api/users/login HTTP/1.1
Host: api.666.com
Content-Type: application/json

{
"email":"sam@qq.com",
"password":"123456"
}

注意要加入Header: "Content-Type","application/json"

响应:

1
2
3
4
{
"code": 200,
"token": "1234567890"
}

代码(GsonRequest.java):

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

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.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

public class GsonRequest<T> extends Request<T> {

private final Gson gson = new Gson();
private final Class<T> clazz;
private Map<String, String> headers;
private final Map<String, String> params;
private final Response.Listener<T> listener;


/**
* Make a POST request and return a parsed object from JSON.
*
* @param url URL of the request to make
* @param clazz Relevant class object, for Gson's reflection
* @param headers Map of request headers
* @param headers Map of request json body
*/
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers, Map<String, String> body,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(Method.POST, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.params = body;
this.listener = listener;
}

public GsonRequest(int type,String url, Class<T> clazz, Map<String, String> headers, Map<String, String> params,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(type, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.params = params;
this.listener = listener;
}

@Override
public byte[] getBody(){

byte[] body = null;
if(params!=null) {
JSONObject jsonObject = new JSONObject(params);
body = jsonObject.toString().getBytes();
}
return body;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {

if(headers == null){
headers = new HashMap<>();
}
headers.put("Content-Type","application/json");

return headers;
}

@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException 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
public void login(String username,
String passwd,
Response.Listener<LoginBean> listener,
Response.ErrorListener error){
final String url = BASE_URL + "/api/users/login";
Map<String ,String >params = new HashMap<>();
params.put("email",username);
params.put("password", passwd);


GsonRequest<LoginBean> gsonRequest = new GsonRequest<>(
url,
LoginBean.class,
null,
params,
listener,
error);
requestQueue.add(request);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class LoginBean {

private int code;
private String token;

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getToken() {
return token;
}

public void setToken(String token) {
this.token = token;
}
}

使用起来就很方便了,监听响应结果。

1
2
3
4
@Override
public void onResponse(LoginBean response) {
Log.d(TAG, "onResponse: "+response.getToken());
}