
com.spothero.volley.JacksonRequest Maven / Gradle / Ivy
/*
* Copyright (C) 2013 SpotHero
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.spothero.volley;
import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpStatus;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JacksonRequest extends Request {
private static final int DEFAULT_TIMEOUT = 30000; // 30 seconds
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private Map mParams;
private List mAcceptedStatusCodes;
private final JacksonRequestListener mListener;
public JacksonRequest(int method, String url, JacksonRequestListener listener) {
this(DEFAULT_TIMEOUT, method, url, null, listener);
}
public JacksonRequest(int timeout, int method, String url, JacksonRequestListener listener) {
this(timeout, method, url, null, listener);
}
public JacksonRequest(int method, String baseUrl, String endpoint, Map params, JacksonRequestListener listener) {
this(DEFAULT_TIMEOUT, method, baseUrl, endpoint, params, listener);
}
public JacksonRequest(int timeout, int method, String baseUrl, String endpoint, Map params, JacksonRequestListener listener) {
this(timeout, method, getUrl(method, baseUrl, endpoint, params), params, listener);
}
public JacksonRequest(int method, String url, Map params, JacksonRequestListener listener) {
this(DEFAULT_TIMEOUT, method, url, params, listener);
}
public JacksonRequest(int timeout, int method, String url, Map params, JacksonRequestListener listener) {
super(method, url, null);
setShouldCache(false);
mListener = listener;
mAcceptedStatusCodes = new ArrayList();
mAcceptedStatusCodes.add(HttpStatus.SC_OK);
mAcceptedStatusCodes.add(HttpStatus.SC_NO_CONTENT);
setRetryPolicy(new DefaultRetryPolicy(timeout, 1, 1));
if (method == Method.POST || method == Method.PUT) {
mParams = params;
}
}
/**
* Gets the ObjectMapper instance used when mapping network responses. Use this to customize the mapper in any way you see fit.
*
* @return The ObjectMapper instance used when mapping network responses
*/
public static ObjectMapper getObjectMapper() {
return OBJECT_MAPPER;
}
/**
* Allows you to add additional status codes (besides 200 and 204) that will be parsed.
*
* @param statusCodes An array of additional status codes to parse network responses for
*/
public void addAcceptedStatusCodes(int[] statusCodes) {
for (int statusCode : statusCodes) {
mAcceptedStatusCodes.add(statusCode);
}
}
/**
* Gets all status codes that will be parsed as successful (Note: some {@link com.android.volley.toolbox.HttpStack}
* implementations, including the default, may not allow certain status codes to be parsed. To get around this
* limitation, use a custom HttpStack, such as the one provided with the excellent OkHttp library
*
* @return A list of all status codes that will be counted as successful
*/
public List getAcceptedStatusCodes() {
return mAcceptedStatusCodes;
}
/**
* Converts a base URL, endpoint, and parameters into a full URL
*
* @param method The {@link com.android.volley.Request.Method} of the URL
* @param baseUrl The base URL
* @param endpoint The endpoint being hit
* @param params The parameters to be appended to the URL if a GET method is used
*
* @return The full URL
*/
private static String getUrl(int method, String baseUrl, String endpoint, Map params) {
if (params != null) {
for (Map.Entry entry : params.entrySet()) {
if (entry.getValue() == null || entry.getValue().equals("null")) {
entry.setValue("");
}
}
}
if (method == Method.GET && params != null && !params.isEmpty()) {
final StringBuilder result = new StringBuilder(baseUrl + endpoint);
final int startLength = result.length();
for (String key : params.keySet()) {
try {
final String encodedKey = URLEncoder.encode(key, "UTF-8");
final String encodedValue = URLEncoder.encode(params.get(key), "UTF-8");
if (result.length() > startLength) {
result.append("&");
} else {
result.append("?");
}
result.append(encodedKey);
result.append("=");
result.append(encodedValue);
} catch (Exception e) { }
}
return result.toString();
} else {
return baseUrl + endpoint;
}
}
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response, HttpStatus.SC_OK, null);
}
@Override
public void deliverError(VolleyError error) {
int statusCode;
if (error != null && error.networkResponse != null) {
statusCode = error.networkResponse.statusCode;
} else {
statusCode = 0;
}
mListener.onResponse(null, statusCode, error);
}
@Override
protected Response parseNetworkResponse(NetworkResponse response) {
JavaType returnType = mListener.getReturnType();
T returnData = null;
if (returnType != null) {
try {
if (response.data != null) {
returnData = OBJECT_MAPPER.readValue(response.data, returnType);
} else if (response instanceof JacksonNetworkResponse) {
returnData = OBJECT_MAPPER.readValue(((JacksonNetworkResponse)response).inputStream, returnType);
}
} catch (Exception e) {
VolleyLog.e(e, "An error occurred while parsing network response:");
return Response.error(new ParseError(response));
}
}
return Response.success(returnData, HttpHeaderParser.parseCacheHeaders(response));
}
@Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("Accept", "application/json");
if (getMethod() == Method.POST || getMethod() == Method.PUT) {
headers.put("Content-Type", "application/x-www-form-urlencoded; charset=utf8");
}
return headers;
}
@Override
public Map getParams() {
return mParams;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy