I have been using volley Library in my app for making network connections. I am able to append parameters in GET and POST requests and both are working fine but couldn't figure out how to do that in a PUT request. I am always getting a "415- status{ Unsupported media type} -result { Invalid content Type}" Error. Did a lot of searching but none worked.
This is what I have tried
RequestQueue requestQueue = VolleyRequests.getInstance().getRequestQueue();
String uri = "https://myURI";
StringRequest request = new StringRequest(Request.Method.PUT, uri, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("server response",response);
userCallBack.done(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("secret_apikey", "xxxxxxx");
headers.put("Content-Type", "application/json");
headers.put("Cache-Control", "no-cache");
headers.put("Accept", "application/json");
return headers;
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("userid", "013");
params.put("sale_amount","2000");
return params;
}};
requestQueue.add(request);
I tried adding the parameters in a byte array as well. this is the code.
#Override
public byte[] getBody() throws AuthFailureError {
byte[] b = null;
JSONObject obj = new JSONObject();
try {
obj.put("userid", "013");
obj.put("sale_amount","2000");
} catch (JSONException e) {
Log.d("Excep", String.valueOf(e));
}
try {
Log.i("json", obj.toString());
b = obj.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
Log.d("Excep", String.valueOf(e));
}
return b;
}
I cannot replace it with a POST or get request because because the API I am calling accepts only PUT requests. Kindly help.
Related
If I send a request with no body everything works. Anyway, when I add the body I get error 400. The body is a JSON converted to String.
Request:
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
key=response;
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),"Fail database",Toast.LENGTH_SHORT).show();
Log.d("tuzzo","err: "+error);
}
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
return params;
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SimpleDateFormat myFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.ITALY);
Map<String, String> params = new HashMap<>();
params.put("nameEx", String.valueOf(prefs.getString("exhtitle",null)));
params.put("descrEx", String.valueOf(prefs.getString("exhdescr",null)));
params.put("longDescr", String.valueOf(longdescr.getText()));
params.put("idCategories", String.valueOf(catmap.get(String.valueOf(spin_cat.getText()).toLowerCase())));
try {
params.put("startDate", myFormat.format(myFormat.parse(startDate.getText().toString())));
params.put("endDate", myFormat.format(myFormat.parse(endDate.getText().toString())));
}catch (ParseException e){
Log.e("testdate","error: "+e);
}
params.put("idMuseums", String.valueOf(musmap.get(String.valueOf(spin_mus.getText()).toLowerCase())));
params.put("chiave", String.valueOf(prefs.getString("exhkey",null)));
return params;
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return full == null ? null : full.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
Log.d("volleyuee", "uee: "+uee);
return null;
}
}
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
};
My server in Python with Flask:
def upd():
data = request.data
if not os.path.exists("/home/tuzzo/stg/res/%s"%request.form['chiave']):
os.makedirs("/home/tuzzo/stg/res/%s"%request.form['chiave'])
os.makedirs("/home/tuzzo/stg/res/%s/download"%request.form['chiave'])
os.makedirs("/home/tuzzo/stg/res/%s/header"%request.form['chiave'])
if not data is None:
with open('/home/tuzzo/stg/res/%s/download/jsonEx.json'%request.form['chiave'], 'w') as outfile:
simplejson.dump(data, outfile)
with open('/home/tuzzo/stg/res/%s/manifest.xml'%request.form['chiave'], 'w') as xmlfile:
xmlfile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?><channel><item><json>http://tuzzo.pythonanywhere.com/download/"+request.form['chiave']+"/jsonEx.json</json></item></channel>")
addEx(request.form['chiave'])
return request.form['chiave']
If I send the String in parameters and I use data = request.form[value] it works, but I don't know what is missing in this request.
Flask views, by default, only respond to GET requests, unless you have a route decorator that specifies that they should also respond to POST (or any other type). Like this:
#app.route('/something', methods=['GET', 'POST'])
def view():
... view code ...
I am trying to send an http post request with raw data .
may be its a duplicate question.. nut i've tried a lot but didn't get any exact solution..
May be there is some minor mistake that i'm not able to understand..
The raw data format is described below
{result_data: [project,circuit]}
what I'm doing:
public void MakeStrRawRequest(final String Tag, String url, final String appData, final ResponseListener responseListener) {
//String uri = String.format(Locale.US, URL);
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "String Success :" + response);
}
},
new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "String Error In Request :" + error.toString());
NetworkResponse response = error.networkResponse;
if (error instanceof ServerError && response != null) {
try {
String res = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, "utf-8"));
// Now you can use any deserializer to make sense of data
//JSONObject obj = new JSONObject(res);
Logger.e(res);
} catch (UnsupportedEncodingException e1) {
// Couldn't properly decode data to string
e1.printStackTrace();
}
}
}
}) {
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
return super.parseNetworkResponse(response);
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("result_data", "[project,circuit]");
// {result_data: [project,circuit]}
return hashMap;
}
#Override
public byte[] getBody() throws AuthFailureError {
return appData.getBytes();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
String AuthToken = "auto_token_value";
headers.put(ApiConstant.TOKEN_KEY, AuthToken);
return headers;
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(15000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
ApplicationData.getInstance().getRequestQueue().add(stringRequest);
}
Here is the response that i'm getting..
BasicNetwork.performRequest: Unexpected response code 400
I've tried both method to send data
1.in getParam() and
2. in getBody()
1. #Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("result_data", "[project,circuit]");
// {result_data: [project,circuit]}
return hashMap;
}
2.
#Override
public byte[] getBody() throws AuthFailureError {
return appData.getBytes();
}
getBody and getParams both are use to send parameters .So, You should call only one method at a time .If you want to send an arbitary string then use getBody() method and on the otherside if you want to send normal parameters then you should use getBody() method.For more detail you may see here
Code for Volley JsonObjectRequest
RequestQueue queue = Volley.newRequestQueue(context);
String url = "https://fcm.googleapis.com/fcm/send";
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.POST, url, null,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response) {
Log.d("ERROR-->", response.toString());
}
},
new ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
Log.d("ERROR-->","error => "+error.toString());
}
}
) {
Overriding header to provide authentication key
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Authorization", "key=AIzaSyB_xxxxx_xxxxxxxxxxxxxxxx");
params.put("Content-Type", "application/json");
String mapAsJson = null;
try {
mapAsJson = new ObjectMapper().writeValueAsString(params);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//Log.d("ERROR",""+mapAsJson);
Log.d("ERROR","-header-->"+params);
return params;
}
#Override
protected Map<String,String> getParams() throws AuthFailureError{
Map<String,String> params = new HashMap<String, String>();
Map<String,String> parent = new HashMap<String, String>();
Map<String,String> child = new HashMap<String, String>();
/* {
"notification":{
"title":"Mandeep ",
"text": "hello"
},
"to": "/topics/mandeep"
}*/
parent.put("title","Mandeep");
parent.put("text","Push Notification");
params.put("notification", String.valueOf(parent));
//params.put("", String.valueOf(child));
params.put("to","/topics/mandeep");
JSONObject obj=new JSONObject(params);
JSONArray array = null;
try {
array=new JSONArray(obj.toString());
} catch (JSONException e) {
e.printStackTrace();
}
//child.put("", String.valueOf(params));
Log.d("ERROR","-msg-->"+params);
return params;
}
#Override
public String getBodyContentType() {
return "application/json";
}
};
queue.add(jsonObjReq);
Error => com.android.volley.ServerError
I tried to make successful requests using POSTMAN and I need help to change the code so that I can make the same request using volley.
From two days i am trying to solve this issue but still i have no any result,why each and every time volley returning me 403 error. where i m wrong? i am using postman to check same webservice, it returns success result. But same thing when i am using in Android via volley or httpurlconnection getting 403 error.kindly help me to find my error.
This is my code which i have tried:
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, Constant.posturl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String result=response;
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
int status = response.statusCode;
}
}) {
#Override
public Map<String, String> getHeaders() {
try {
headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
String credentials = Constant.USERNAME + ":" + Constant.PASSWORD;
String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);
headers.put("Authorization", auth);
return headers;
} catch (Exception e) {
e.printStackTrace();
return headers;
}
}
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("title", heading_edit_text.getText().toString());
params.put("content", body_edit_text.getText().toString());
params.put("Slug", heading_edit_text.getText().toString());
params.put("date", currentDate);
return params;
}
};
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(50000, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsonObjectRequest);
Volley does provide a proper request for this which is called JsonObjectRequest.
String webAddress = "url here";
RequestQueue queue = Volley.newRequestQueue(this); // singletone here
JSONObject object = new JSONObject();
try {
object.put("title", heading_edit_text.getText().toString());
object.put("content", body_edit_text.getText().toString());
object.put("Slug", heading_edit_text.getText().toString());
object.put("date", currentDate);
} catch (JSONException e) {
}
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, webAddress,object, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject object) {
Log.d("RESPONSE", object.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d("RESPONSE", "That didn't work!");
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> header = new HashMap<>();
// content type is not needed here
header.put("Authorization", "value here");
return header;
}
};
queue.add(request);
Change the "Content-Type" of your headers to "application/form-data"
ie,
headers.put("Content-Type", "application/form-data");
I was also face this issue in news api. But when I use Retrfit its work like a charm.
I am trying hit an api(written in PHP) and posting params with it.
Here is my code:
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, null,
new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println("prerna succes volley "+response.toString());
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("prerna fail volley "+error.toString());
}
})
{
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> pars = new HashMap<String, String>();
pars.put("Content-Type", "application/x-www-form-urlencoded");
return pars;
}
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("action", "login");
params.put("username", "abc#xyz.com");
params.put("pass", "a");
return params;
}
};
I always get invalid username/password which has been handled in api in case there is invalid username and password.In this case api is not receiving the params.
I tried to do it with retrofit and its working fine with it that means there is no problem at API coding. What am I missing here in case of volley?
Thanks for the support. I am able to solve the problem by changing JsonObjectRequest to StringRequest. i found Volley JsonObjectRequest Post parameters no longer work where I got to know that JsonObjectRequest creates some unexpected problems.
There is my code:
StringRequest jsonObjReq = new StringRequest(Request.Method.POST,
url,
new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response.toString());
String no = jsonObject.getString("$PhoneNo");
} catch (JSONException e) {
}
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("prerna fail volley " + error.toString());
}
})
{
#Override
public String getBodyContentType() {
Map<String, String> pars = new HashMap<String, String>();
pars.put("Content-Type", "application/x-www-form-urlencoded");
//return pars;
return "application/x-www-form-urlencoded";
}
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("action", "login");
params.put("username", "abc#xyz.com");
params.put("pass", "a");
return params;
}
};
However I am still trying to figure out why JsonobjectRequest did not work.
As far as I can tell by looking at JsonObjectRequest your 3rd parameter is null, and it indicates the JsonObject request - by the documentation "jsonRequest - A JSONObject to post with the request. Null is allowed and indicates no parameters will be posted along with request."
And after searching again, I saw this thread.
if you are sending your data in raw format you need to try this,first of all make json of your data to be post.
final JSONObject jsonBody = new JSONObject();
jsonBody.put("mobile", phoneNumber);
jsonBody.put("otp", otp.trim());
and you have to override these methods
#Override
public byte[] getBody() throws AuthFailureError {
return jsonBody.toString().getBytes();
}
#Override
public String getBodyContentType() {
return "application/json";
}
if you also have header in your post request you also send that with by following type
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
String auth_token = "bearer" + prefs.getPreferencesString(context, "AuthToken").toString();
params.put("Authorization", auth_token);
return params;
}
Here is the whole code.
final JSONObject jsonBody = new JSONObject();
jsonBody.put("mobile", phoneNumber);
jsonBody.put("otp", otp.trim());
StringRequest sr = new StringRequest(Request.Method.POST, Constraints.Base_URL + "/api/v1/verifyotp", new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
progressDialog.dismiss();
JSONObject jsonObject = new JSONObject(response);
int status = jsonObject.getInt("status");
String token = jsonObject.getString("token");
prefs.setPreferencesString(OtpActivity.this, "AuthToken", token);
if (status == 1) {
startActivity(new Intent(getApplicationContext(), WelcomeScreenActivity.class));
overridePendingTransition(R.anim.right_in, R.anim.left_out);
} else if (status == 0) {
Toast.makeText(OtpActivity.this, "Please Enter Otp!", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
}
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(OtpActivity.this, "Invalid otp please try again!!", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
return jsonBody.toString().getBytes();
}
#Override
public String getBodyContentType() {
return "application/json";
}
};
MyApplication.getInstance().addToReqQueue(sr, "jreq");
}
} catch (Exception e) {
}
Try migrating to getHeaders and remove getParams
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("action", "login");
params.put("username", "abc#xyz.com");
params.put("pass", "a");
return pars;
}
Or - Reuse the getParams method
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = getParams();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
If it is a body request all you need to do is add the extra parameter.
JSONObject body = new JSONObject();
body.put("action", "login");
body.put("username", "abc#xyz.com");
body.put("pass", "a");
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, body,
new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println("prerna succes volley "+response.toString());
}
},
new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("prerna fail volley "+error.toString());
}
});