Creating a parsed Jackson query in Volley

I want to create a JacksonJSONRequest implementation in Volley. My requests / responses, like most, will have a request object of type X and a response object of type Y.

The base class of the Volley request is defined as the same ...

public class JacksonRequest<T> extends Request<T> ... protected Response<T> parseNetworkResponse(NetworkResponse response) 

It doesn't really matter to me. I cannot submit many REST requests using the same structure for request and responses.

Did I miss something obvious here?

+4
source share
2 answers

Here is my implementation ...

 public class JacksonRequest<T> extends JsonRequest<T> { private Class<T> responseType; /** * Creates a new request. * * @param method * the HTTP method to use * @param url * URL to fetch the JSON from * @param requestData * A {@link Object} to post and convert into json as the request. Null is allowed and indicates no parameters will be posted along with request. * @param listener * Listener to receive the JSON response * @param errorListener * Error listener, or null to ignore errors. */ public JacksonRequest(int method, String url, Object requestData, Class<T> responseType, Listener<T> listener, ErrorListener errorListener) { super(method, url, (requestData == null) ? null : Mapper.string(requestData), listener, errorListener); this.responseType = responseType; } @Override protected Response<T> parseNetworkResponse(NetworkResponse response) { try { String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); return Response.success(Mapper.objectOrThrow(jsonString, responseType), HttpHeaderParser.parseCacheHeaders(response)); } catch (Exception e) { return Response.error(new ParseError(e)); } } } 

The Mapper class used above is just a small wrapper class ...

 /** * Singleton wrapper class which configures the Jackson JSON parser. */ public final class Mapper { private static ObjectMapper MAPPER; public static ObjectMapper get() { if (MAPPER == null) { MAPPER = new ObjectMapper(); // This is useful for me in case I add new object properties on the server side which are not yet available on the client. MAPPER.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); } return MAPPER; } public static String string(Object data) { try { return get().writeValueAsString(data); } catch (Exception e) { e.printStackTrace(); return null; } } public static <T> T objectOrThrow(String data, Class<T> type) throws JsonParseException, JsonMappingException, IOException { return get().readValue(data, type); } public static <T> T object(String data, Class<T> type) { try { return objectOrThrow(data, type); } catch (Exception e) { e.printStackTrace(); return null; } } } 
+4
source

Not sure if this will help you, but I have a jackson request that takes a type and returns a string, I use it because most of my requests just return a header

Edit

It has different types of requests and responses, it is not super elegant, but it works

 public class JacksonJsonRequest<K, T> extends Request<T> { private ObjectMapper mMapper = new ObjectMapper(); private static final String PROTOCOL_CHARSET = "utf-8"; private static final String PROTOCOL_CONTENT_TYPE = String.format("application/json; charset=%s", PROTOCOL_CHARSET); private final Response.Listener<T> mListener; private final K mRequestBody; private final Class<T> mClass; private final Map<String, String> mHeaders; public JacksonJsonRequest(int method, String url, K requestBody, Response.ErrorListener errorListener, Response.Listener<T> listener, Map<String, String> headers, Class<T> claz) { super(method, url, errorListener); mListener = listener; mRequestBody = requestBody; mHeaders = headers; mClass = claz; } @Override protected Response<T> parseNetworkResponse(NetworkResponse networkResponse) { String jsonString = new String(networkResponse.data); try { T result = mMapper.readValue(jsonString, mClass); return Response.success(result, HttpHeaderParser.parseCacheHeaders(networkResponse)); } catch (IOException e) { Log.e("jacksontest", "error parsing", e); } return null; } @Override protected void deliverResponse(T t) { mListener.onResponse(t); } @Override public String getBodyContentType() { return PROTOCOL_CONTENT_TYPE; } @Override public byte[] getBody() { try { return mRequestBody == null ? null : mMapper.writeValueAsBytes(mRequestBody); } catch (JsonProcessingException e) { Log.e("Jacksontest", "error parsing", e); } return null; } @Override public Map<String, String> getHeaders() throws AuthFailureError { return (mHeaders == null) ? super.getHeaders() : mHeaders; } 

}

0
source

Source: https://habr.com/ru/post/1488436/


All Articles