我有以下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"
}
]
}
]
}
我为GSON请求创建了以下类。如何使用排球请求发出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;
}
}
答案 0 :(得分:25)
只需创建一个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));
}
}
}
现在在您的类文件(Activity)中,只需按如下方式调用此类:
RequestQueue queue = MyVolley.getRequestQueue();
GsonRequest<MyClass> myReq = new GsonRequest<MyClass>(Method.GET,
"http://JSONURL/",
TagList.class,
createMyReqSuccessListener(),
createMyReqErrorListener());
queue.add(myReq);
我们还需要创建两个方法 -
createMyReqSuccessListener()
- 收到GsonRequest
createMyReqErrorListener()
- 处理任何错误如下:
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.
}
};
}
和
private Response.ErrorListener createMyReqErrorListener() {
return new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Do whatever you want to do with error.getMessage();
}
};
}
我希望它会有所帮助。
答案 1 :(得分:7)
这里有一些有用的代码片段。
GasonRequest for GET foritions:
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));
}
}
}
GasonRequest for POST foritions:
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));
}
}
}
这是您将它用于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
);
}
这就是你如何将它用于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
);
}
这是您将其用于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,您有一个blog post about how to use OkHttp, Volley and Gson here.
答案 2 :(得分:2)
我刚刚制作了一个基于Jackson库而不是Gson的自定义json请求。
我想指出一件事(花了我很多时间才弄明白......):如果你也想支持POST Json参数,你应该从JsonRequest而不是Request扩展。否则你的Json请求体将被url编码,在服务器端你不能将它转换回java对象。
这是我的json请求类,它基于Jackson并支持Json参数和标题:
public class JacksonRequest<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 JacksonRequest(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 JacksonRequest(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;
}
}
}