Skip to content

Instantly share code, notes, and snippets.

@josiahneuberger
Last active August 29, 2015 14:20
Show Gist options
  • Save josiahneuberger/24a9e09c11b705ce7cb8 to your computer and use it in GitHub Desktop.
Save josiahneuberger/24a9e09c11b705ce7cb8 to your computer and use it in GitHub Desktop.
Fixing Volley Request for Patch and PUT adding blank entry to JSON endpoints
/****
* Using Volley to PUT or PATCH a JSON endpoint creates an empty entry in your JSON:
*
* {
* "id": 7,
* "favorite": true,
* "": ""
* }
*
* The bug is in line 457 of Request.java in the Volley source:
* https://android.googlesource.com/platform/frameworks/volley/+/l-preview/src/com/android/volley/Request.java
*
private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
encodedParams.append('&');
}
return encodedParams.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
*
* The loop is adding an extra '&' at the end. A quick hack to fix this is to create a static
* encodeParams() function in your VolleyManager singleton, which you call from getBody(), which
* you override in your request object.
*
*/
/**
* Place this file inside some globally accessible point such as your Volley singleton.
* I've only changed line 47, which takes out the final '&'.
*/
public static byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
encodedParams.append('&');
}
encodedParams.replace(encodedParams.length()-1, encodedParams.length(), "");
return encodedParams.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
/***
* An example string request. The important piece is the getBody() function.
*/
VolleyManager.getInstance().addToRequestQueue(new StringRequest(Request.Method.PATCH, http://127.0.0.1/contacts/7,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
new AlertDialog.Builder(mContext)
.setMessage(response.substring(0, 200)).create().show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i("Volley", error.getMessage());
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("favorite", String.valueOf(false));
return params;
}
/**
* This will call our new encodeParams function, which doesn't add a blank entry in our JSON.
* The code is pulled directly from Request.java only changing line 89 by calling our fixed encodeParams().
*/
@Override
public byte[] getBody() throws AuthFailureError {
Map<String, String> params = getParams();
if (params != null && params.size() > 0) {
return VolleyManager.encodeParameters(params, getParamsEncoding());
}
return null;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment