Android 使用 volley 发出 GSON 请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24537875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
making a GSON request using volley
提问by Abhay Sood
I have the following json response
我有以下 json 响应
{
"tag": [
{
"listing_count": 5,
"listings": [
{
"source": "source1",
"data": {
"image": "image1",
"name": "name1"
},
"name": "name1"
}
]
},
{
"listing_count": 5,
"listings": [
{
"source": "source2",
"data": {
"image": "imag2",
"name": "name2"
},
"name": "name2"
}
]
}
]
}
I have created the following classes for GSON request. How do I make the GSON request and store the values for the response using a volley request. What should the GSON request be like?
我为 GSON 请求创建了以下类。如何使用 volley 请求发出 GSON 请求并存储响应值。GSON 请求应该是什么样的?
public class TagList {
ArrayList<Tag> tags;
public static class Tag {
int listing_count;
ArrayList<Listings> listings;
public int getListing_count() {
return listing_count;
}
public void setListing_count(int listing_count) {
this.listing_count = listing_count;
}
public ArrayList<Listings> getListings() {
return listings;
}
public void setListings(ArrayList<Listings> listings) {
this.listings = listings;
}
}
public static class Listings {
String source;
Data data;
String name;
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static class Data {
String image;
String name;
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
回答by MSN
Just create a GsonRequest
Class as follows (taken from Android Developer Docs)
只需GsonRequest
按如下方式创建一个类(取自Android Developer Docs)
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final 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 GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, 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));
}
}
}
Now in your class file (Activity) just call the this class as follows:
现在在您的类文件(活动)中,只需按如下方式调用此类:
RequestQueue queue = MyVolley.getRequestQueue();
GsonRequest<MyClass> myReq = new GsonRequest<MyClass>(Method.GET,
"http://JSONURL/",
TagList.class,
createMyReqSuccessListener(),
createMyReqErrorListener());
queue.add(myReq);
We also need to create two methods -
我们还需要创建两个方法——
createMyReqSuccessListener()
- receive the response fromGsonRequest
createMyReqErrorListener()
- to handle any error
createMyReqSuccessListener()
- 收到来自GsonRequest
createMyReqErrorListener()
- 处理任何错误
as follows:
如下:
private Response.Listener<MyClass> createMyReqSuccessListener() {
return new Response.Listener<MyClass>() {
@Override
public void onResponse(MyClass response) {
// Do whatever you want to do with response;
// Like response.tags.getListing_count(); etc. etc.
}
};
}
and
和
private Response.ErrorListener createMyReqErrorListener() {
return new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Do whatever you want to do with error.getMessage();
}
};
}
I hope it will make some sense.
我希望它会有意义。
回答by Sotti
Here some useful code snippets.
这里有一些有用的代码片段。
GsonRequest for GET petitions:
GET 请求的 GsonRequest:
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.lang.reflect.Type;
/**
* Convert a JsonElement into a list of objects or an object with Google Gson.
*
* The JsonElement is the response object for a {@link com.android.volley.Request.Method} GET call.
*
* @author https://plus.google.com/+PabloCostaTirado/about
*/
public class GsonGetRequest<T> extends Request<T>
{
private final Gson gson;
private final Type type;
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 type is the type of the object to be returned
* @param listener is the listener for the right answer
* @param errorListener is the listener for the wrong answer
*/
public GsonGetRequest
(String url, Type type, Gson gson,
Response.Listener<T> listener, Response.ErrorListener errorListener)
{
super(Method.GET, url, errorListener);
this.gson = gson;
this.type = type;
this.listener = listener;
}
@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<T>) Response.success
(
gson.fromJson(json, type),
HttpHeaderParser.parseCacheHeaders(response)
);
}
catch (UnsupportedEncodingException e)
{
return Response.error(new ParseError(e));
}
catch (JsonSyntaxException e)
{
return Response.error(new ParseError(e));
}
}
}
GsonRequest for POST petitions:
POST 请求的 GsonRequest:
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonRequest;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
/**
* Convert a JsonElement into a list of objects or an object with Google Gson.
*
* The JsonElement is the response object for a {@link com.android.volley.Request.Method} POST call.
*
* @author https://plus.google.com/+PabloCostaTirado/about
*/
public class GsonPostRequest<T> extends JsonRequest<T>
{
private final Gson gson;
private final Type type;
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 type is the type of the object to be returned
* @param listener is the listener for the right answer
* @param errorListener is the listener for the wrong answer
*/
public GsonPostRequest
(String url, String body, Type type, Gson gson,
Response.Listener<T> listener, Response.ErrorListener errorListener)
{
super(Method.POST, url, body, listener, errorListener);
this.gson = gson;
this.type = type;
this.listener = listener;
}
@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<T>) Response.success
(
gson.fromJson(json, type),
HttpHeaderParser.parseCacheHeaders(response)
);
}
catch (UnsupportedEncodingException e)
{
return Response.error(new ParseError(e));
}
catch (JsonSyntaxException e)
{
return Response.error(new ParseError(e));
}
}
}
This is how you use it for JSON objects:
这是您将它用于 JSON 对象的方式:
/**
* Returns a dummy object
*
* @param listener is the listener for the correct answer
* @param errorListener is the listener for the error response
*
* @return @return {@link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonGetRequest}
*/
public static GsonGetRequest<DummyObject> getDummyObject
(
Response.Listener<DummyObject> listener,
Response.ErrorListener errorListener
)
{
final String url = "http://www.mocky.io/v2/55973508b0e9e4a71a02f05f";
final Gson gson = new GsonBuilder()
.registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
.create();
return new GsonGetRequest<>
(
url,
new TypeToken<DummyObject>() {}.getType(),
gson,
listener,
errorListener
);
}
This is how you use it for JSON arrays:
这是将它用于 JSON 数组的方式:
/**
* Returns a dummy object's array
*
* @param listener is the listener for the correct answer
* @param errorListener is the listener for the error response
*
* @return {@link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonGetRequest}
*/
public static GsonGetRequest<ArrayList<DummyObject>> getDummyObjectArray
(
Response.Listener<ArrayList<DummyObject>> listener,
Response.ErrorListener errorListener
)
{
final String url = "http://www.mocky.io/v2/5597d86a6344715505576725";
final Gson gson = new GsonBuilder()
.registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
.create();
return new GsonGetRequest<>
(
url,
new TypeToken<ArrayList<DummyObject>>() {}.getType(),
gson,
listener,
errorListener
);
}
This is how you use it for POST calls:
这是您将其用于 POST 调用的方式:
/**
* An example call (not used in this example app) to demonstrate how to do a Volley POST call
* and parse the response with Gson.
*
* @param listener is the listener for the success response
* @param errorListener is the listener for the error response
*
* @return {@link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonPostRequest}
*/
public static GsonPostRequest getDummyObjectArrayWithPost
(
Response.Listener<DummyObject> listener,
Response.ErrorListener errorListener
)
{
final String url = "http://PostApiEndpoint";
final Gson gson = new GsonBuilder()
.registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
.create();
final JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name", "Ficus");
jsonObject.addProperty("surname", "Kirkpatrick");
final JsonArray squareGuys = new JsonArray();
final JsonObject dev1 = new JsonObject();
final JsonObject dev2 = new JsonObject();
dev1.addProperty("name", "Jake Wharton");
dev2.addProperty("name", "Jesse Wilson");
squareGuys.add(dev1);
squareGuys.add(dev2);
jsonObject.add("squareGuys", squareGuys);
return new GsonPostRequest<>
(
url,
jsonObject.toString(),
new TypeToken<DummyObject>()
{
}.getType(),
gson,
listener,
errorListener
);
}
}
All the code is taken from here, and you have a blog post about how to use OkHttp, Volley and Gson here.
回答by cn123h
I just made a custom json request which is based on Hymanson library instead of Gson.
我刚刚提出了一个基于 Hymanson 库而不是 Gson 的自定义 json 请求。
One thing I want to point out (it took my many hours to figure out...): if you want to support POST Json parameter as well, you should extend from JsonRequest instead of Request. Otherwise your Json request body will be url-encoded, on the server side you cannot convert it back to java object.
我想指出的一件事(我花了好几个小时才弄明白……):如果你也想支持 POST Json 参数,你应该从 JsonRequest 而不是 Request 扩展。否则您的 Json 请求正文将被 url 编码,在服务器端您无法将其转换回 java 对象。
Here is my json request class, which is based on Hymanson and supports Json parameter and header:
这是我的 json 请求类,它基于 Hymanson 并支持 Json 参数和标头:
public class HymansonRequest<ResponseType> extends JsonRequest<ResponseType> {
private final ObjectMapper objectMapper = new ObjectMapper();
private final Class<ResponseType> responseClass;
private final Map<String, String> headers;
private String requestBody = null;
private static final String PROTOCOL_CHARSET = "utf-8";
/**
* POST method without header
*/
public HymansonRequest(String url,
Object parameterObject,
Class<ResponseType> responseClass,
Response.Listener<ResponseType> listener,
Response.ErrorListener errorListener) {
this(Method.POST, url, null, parameterObject, responseClass, listener, errorListener);
}
/**
* @param method see also com.android.volley.Request.Method
*/
public HymansonRequest(int method,
String url,
Map<String, String> headers,
Object parameterObject,
Class<ResponseType> responseClass,
Response.Listener<ResponseType> listener,
Response.ErrorListener errorListener) {
super(method, url, null, listener, errorListener);
if (parameterObject != null)
try {
this.requestBody = objectMapper.writeValueAsString(parameterObject);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
this.headers = headers;
this.responseClass = responseClass;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
@Override
protected Response<ResponseType> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
ResponseType result = objectMapper.readValue(json, responseClass);
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonMappingException e) {
return Response.error(new ParseError(e));
} catch (JsonParseException e) {
return Response.error(new ParseError(e));
} catch (IOException e) {
return Response.error(new ParseError(e));
}
}
/**
* Cannot call objectMapper.writeValueAsString() before super constructor, so override the same getBody() here.
*/
@Override
public byte[] getBody() {
try {
return requestBody == null ? null : requestBody.getBytes(PROTOCOL_CHARSET);
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
requestBody, PROTOCOL_CHARSET);
return null;
}
}
}