Tôi biết rằng chủ đề này khá cũ, nhưng tôi đã gặp vấn đề này và tôi đã đưa ra một giải pháp tuyệt vời có thể rất hữu ích cho nhiều người vì nó sửa / mở rộng thư viện Volley trên nhiều khía cạnh.
Tôi phát hiện một số tính năng Volley không được hỗ trợ:
- Điều này
JSONObjectRequest
không hoàn hảo: bạn phải mong đợi một JSON
ở cuối (xem phần Response.Listener<JSONObject>
).
- Còn về Phản hồi trống (chỉ với trạng thái 200) thì sao?
- Tôi phải làm gì nếu muốn trực tiếp POJO của mình từ
ResponseListener
?
Ít nhiều tôi đã biên soạn rất nhiều giải pháp trong một lớp học chung chung lớn để có giải pháp cho tất cả các vấn đề mà tôi đã trích dẫn.
public class GenericRequest<T> extends JsonRequest<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private boolean muteRequest = false;
private GenericRequest(int method, Class<T> classtype, String url, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
super(method, url, requestBody, listener,
errorListener);
clazz = classtype;
this.headers = headers;
configureRequest();
}
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, headers);
}
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, new HashMap<String, String>());
}
public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(method, classtype, url, requestBody, listener,
errorListener, new HashMap<String, String>());
}
public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(Request.Method.GET, url, classtype, "", listener, errorListener);
}
public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
this(Request.Method.GET, classtype, url, "", listener, errorListener, headers);
}
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers, boolean mute) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, headers);
this.muteRequest = mute;
}
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, new HashMap<String, String>());
this.muteRequest = mute;
}
public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
this(method, classtype, url, requestBody, listener,
errorListener, new HashMap<String, String>());
this.muteRequest = mute;
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
if (muteRequest) {
if (response.statusCode >= 200 && response.statusCode <= 299) {
return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
}
} else {
try {
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
T parsedObject = gson.fromJson(json, clazz);
return Response.success(parsedObject, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
return null;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
private void configureRequest() {
}
}
Nó có vẻ hơi quá mức cần thiết nhưng thật tuyệt khi có tất cả các hàm tạo này vì bạn có tất cả các trường hợp:
(Hàm tạo chính không được sử dụng trực tiếp mặc dù tất nhiên là có thể).
- Yêu cầu với phản hồi được phân tích cú pháp thành POJO / Tiêu đề được đặt theo cách thủ công / POJO thành Gửi
- Yêu cầu với phản hồi được phân tích cú pháp thành POJO / POJO để gửi
- Yêu cầu với phản hồi được phân tích cú pháp thành POJO / Chuỗi để gửi
- Yêu cầu với phản hồi được phân tích cú pháp thành POJO (GET)
- Yêu cầu với phản hồi được phân tích cú pháp thành POJO (GET) / Tiêu đề được đặt theo cách thủ công
- Yêu cầu không có phản hồi (200 - Phần nội dung trống) / Tiêu đề được đặt theo cách thủ công / POJO để gửi
- Yêu cầu không có phản hồi (200 - Nội dung trống) / POJO để gửi
- Yêu cầu không có phản hồi (200 - Nội dung trống) / Chuỗi để gửi
Tất nhiên, để nó hoạt động, bạn phải có GSON Lib của Google; chỉ cần thêm:
compile 'com.google.code.gson:gson:x.y.z'
cho các phụ thuộc của bạn (phiên bản hiện tại là 2.3.1
).
HashMap
là loại thừa trong ví dụ của bạn. Bạn có thể đặt trực tiếp 'mã thông báo' vào aJSONObject
mà không cần bản đồ trung gian.