Делая запрос GSON, используя залп
У меня есть следующий ответ 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;
}
}
Ответы
Ответ 1
Просто создайте класс 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 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();
}
};
}
Надеюсь, это будет иметь смысл.
Ответ 2
Вот некоторые полезные фрагменты кода.
GsonRequest для запросов GET:
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 для петиций POST:
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 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
);
}
}
Весь код взят отсюда, и у вас есть блог сообщение о том, как использовать OkHttp, Volley и Gson здесь.
Ответ 3
Я просто создал пользовательский запрос json, который основан на библиотеке Джексона вместо Gson.
Одна вещь, которую я хочу указать (мне потребовалось много часов, чтобы понять...): если вы хотите также поддерживать параметр 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;
}
}
}