I tried to update the data of my server with Volley by means of the PATCH method sending the data in a body, the form is the following:
String url = getString(R.string.ws_base) + getString(R.string.ws_ip) + getString(R.string.ws_servicios);
String wsUsuario ="";
if(SingletonUsuario.getInstance().getUsuario().getTipoUsuario() == Usuario.TIPO_CONDUCTOR){
wsUsuario = getString(R.string.ws_conductores);
}else {
wsUsuario = getString(R.string.ws_pasajeros);
}
url += wsUsuario + SingletonUsuario.getInstance().getUsuario().getDni()+"/";
MyApplication.volleyQueueInstance.cancelRequestInQueue(SEND_REGISTRATION_TOKEN_SERVER);
JSONObject body = new JSONObject();
try {
body.put("firebase_token", token);
} catch (JSONException e) { e.printStackTrace(); }
//build Get url of Place Autocomplete and hit the url to fetch result.
HashMap<String, String> head = new HashMap<String, String>();
head.put(HEADER_CONTENT_TYPE, HEADER_JSON);
head.put(HEADER_AUTHORIZATION, TOKEN + " " + SingletonUsuario.getInstance().getUsuario().getTokenOauth());
VolleyJSONRequest request = new VolleyJSONRequest(Request.Method.PATCH, url, body.toString(), head, MyFirebaseInstanceIDService.this, MyFirebaseInstanceIDService.this);
//Give a tag to your request so that you can use this tag to cancle request later.
request.setTag(SEND_REGISTRATION_TOKEN_SERVER);
MyApplication.volleyQueueInstance.addToRequestQueue(request);
In the server it says to me like that it can not read the body, the same request I do it with HttpClient and it works correctly, in the following way: (I send the same variables that I used in the previous code)
RestCustomer r = new RestCustomer(this, url, body, Constantes.PATCH, SingletonUsuario.getInstance().getUsuario().getTokenOauth());
r.execute();
And within my RestCustomer I have:
protected String doInBackground(Void... params) {
String objetoRespuesta = null;
try {
HttpClient hc = new DefaultHttpClient();
String message = body.toString();
HttpUriRequest request = null;
switch (metodo) {
case Constantes.POST:
HttpPost httpPost = new HttpPost(url.toString());
httpPost.setEntity(new StringEntity(message, "UTF8"));
httpPost.setHeader("Content-type", "application/json");
if (header != null) {
httpPost.addHeader("Authorization", "Token " + header);
}
request = httpPost;
break;
case Constantes.GET:
HttpGet httpGet = new HttpGet(url.toString());
//httpGet.setEntity(new StringEntity(message, "UTF8"));
httpGet.setHeader("Content-type", "application/json");
request = new HttpGet(url.toString());
break;
case Constantes.PATCH:
HttpClientStack.HttpPatch httpPatch = new HttpClientStack.HttpPatch(url.toString());
httpPatch.setEntity(new StringEntity(message, "UTF8"));
httpPatch.setHeader("Content-type", "application/json");
if (header != null) {
httpPatch.addHeader("Authorization", "Token " + header);
}
request = httpPatch;
}
//p.setEntity(new StringEntity(message, "UTF8"));
//p.setHeader("Content-type", "application/json");
HttpResponse resp = hc.execute(request);
if (resp != null) {
if (resp.getStatusLine().getStatusCode() == 204)
result = resp.getStatusLine().toString();
}
objetoRespuesta = EntityUtils.toString(resp.getEntity());
Log.d("Status line", "" + resp.getStatusLine().getStatusCode());
} catch (Exception e) {
Log.e("RestCustomer: ", e.getMessage(), e);
result = e.getMessage();
}
return objetoRespuesta;
}
This is correct, the only difference I see is that the message (body) sends the "UTF8", how could I send it in my Volley? I leave the Volley class I use:
public class VolleyJSONRequest extends JsonRequest<String> {
String mUrl;
private Response.Listener<String> listener;
private Response.ErrorListener errorListener;
private Map<String, String> headers = new HashMap<>();
public VolleyJSONRequest(int method, String url, String params, HashMap<String, String> head, Response.Listener<String> listener, Response.ErrorListener errorListener) {
super(method, url, params, listener, errorListener);
this.listener = listener;
this.errorListener = errorListener;
this.mUrl = url;
if(head!=null){
headers.putAll(head);
}
headers.put("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; google_sdk Build/MR1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");
headers.put("Accept", "application/json");
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers;
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
try {
// Volley does not handle null properly, so implement null response
// check
if (response.data.length == 0) {
byte[] responseData = "{}".getBytes("UTF8");
response = new NetworkResponse(response.statusCode,
responseData, response.headers, response.notModified);
}
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
jsonString,
parseIgnoreCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
System.out.println("VolleyQueue: Encoding Error for " + getTag()
+ " (" + getSequence() + ")");
return Response.error(new ParseError(e));
}
}
/**
* Extracts a {@link Cache.Entry} from a {@link NetworkResponse}.
* Cache-control headers are ignored. SoftTtl == 15 mins, ttl == 24 hours.
*
* @param response The network response to parse headers from
* @return a cache entry for the given response, or null if the response is
* not cacheable.
*/
public Cache.Entry parseIgnoreCacheHeaders(NetworkResponse response) {
long now = System.currentTimeMillis();
Map<String, String> headers = response.headers;
long serverDate = 0;
String serverEtag = null;
String headerValue;
headerValue = headers.get("Date");
if (headerValue != null) {
serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
serverEtag = headers.get("ETag");
long cacheHitButRefreshed = 0;
long cacheExpired = 0;
cacheExpired = 0; //change value if caching required
cacheHitButRefreshed = 0;
final long softExpire = now + cacheHitButRefreshed;
final long ttl = now + cacheExpired;
Cache.Entry entry = new Cache.Entry();
entry.data = response.data;
entry.etag = serverEtag;
entry.softTtl = softExpire;
entry.ttl = ttl;
entry.serverDate = serverDate;
entry.responseHeaders = headers;
return entry;
}
@Override
protected void deliverResponse(String response) {
listener.onResponse(response);
}
@Override
public void deliverError(VolleyError error) {
super.deliverError(error);
}
}
Class from which Volley extends:
public abstract class JsonRequest<T> extends Request<T> {
/** Default charset for JSON request. */
protected static final String PROTOCOL_CHARSET = "utf-8";
/** Content type for request. */
private static final String PROTOCOL_CONTENT_TYPE =
String.format("application/json; charset=%s", PROTOCOL_CHARSET);
private Listener<T> mListener;
private final String mRequestBody;
/**
* Deprecated constructor for a JsonRequest which defaults to GET unless {@link #getPostBody()}
* or {@link #getPostParams()} is overridden (which defaults to POST).
*
* @deprecated Use {@link #JsonRequest(int, String, String, Listener, ErrorListener)}.
*/
public JsonRequest(String url, String requestBody, Listener<T> listener,
ErrorListener errorListener) {
this(Method.DEPRECATED_GET_OR_POST, url, requestBody, listener, errorListener);
}
public JsonRequest(int method, String url, String requestBody, Listener<T> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
mRequestBody = requestBody;
}
@Override
protected void onFinish() {
super.onFinish();
mListener = null;
}
@Override
protected void deliverResponse(T response) {
if (mListener != null) {
mListener.onResponse(response);
}
}
@Override
abstract protected Response<T> parseNetworkResponse(NetworkResponse response);
/**
* @deprecated Use {@link #getBodyContentType()}.
*/
@Override
public String getPostBodyContentType() {
return getBodyContentType();
}
/**
* @deprecated Use {@link #getBody()}.
*/
@Override
public byte[] getPostBody() {
return getBody();
}
@Override
public String getBodyContentType() {
return PROTOCOL_CONTENT_TYPE;
}
@Override
public byte[] getBody() {
try {
return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
mRequestBody, PROTOCOL_CHARSET);
return null;
}
}
}
The server returns 415, does not understand what I send in the body.
Any help is welcome, thank you very much. Greetings.