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
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 looking to do as per the image says:
Following is the code I am trying to implement from that image:
RequestQueue queue = Volley.newRequestQueue(this);
String url ="https://api.kairos.com/enroll";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
Log.i("Response is: " , response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// mTextView.setText("That didn't work!");
}
})
{
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("app_id", "4985f625");
params.put("app_key", "aa9e5d2ec3b00306b2d9588c3a25d68e");
return params;
}
};
// Add the request to the RequestQueue.
queue.add(stringRequest);
Now I do not get how to add that JSONObject part into my POST Request, and also how to add the Content-Type Header.
I found a similar question here. See the code below. You have to override the getBodyContentType method.
public String getBodyContentType()
{
return "application/json";
}
for content type header you can do the following
StringRequest request = new StringRequest(Request.Method.PUT,
url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
listener.onResponse(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(#NonNull VolleyError error) {
if (error.networkResponse != null) {
errorListener.onErrorResponse(error.networkResponse.statusCode, null);
} else {
Log.e(TAG, "An error occurred while trying to verify sms: ", error);
errorListener.onErrorResponse(500, null);
}
}
}) {
#NonNull
#Override
protected Map<String, String> getParams() {
return data;
}
#NonNull
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type",
"application/x-www-form-urlencoded");
return headers;
}
};
And for send Json object I suggest create Json object like this
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("11", 3);
jsonObject.put("12", 4);
jsonObject.put("13", 5);
} catch (JSONException e) {
e.printStackTrace();
}
Then you can pass this object as string by jsonObject.toString() and pass it in parameters like pass any string like the following
#NonNull
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("json", jsonObject.toString();
return params;
}
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());
}
});
I am using StringRequest to send the Files to server. I am using the following code:
final MultipartEntityBuilder mHttpEntity = buildMultipartEntity(files_to_upload, params);
Response.Listener<String> rListner = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if(response != null) {
Intent intent = new Intent(Constants.ACTION_RESPONSE_RECEIVED);
intent.putExtra(Constants.RESPONSE, response);
intent.putExtra(SignupActivity.EXTRA_ACTION_RESPONSE, SignupActivity.EXTRA_SIGNUP_DATA);
LocalBroadcastManager.getInstance(MyApplication.getContext()).sendBroadcast(intent);
}
}
};
Response.ErrorListener errorListner = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Intent intent = new Intent(Constants.ACTION_RESPONSE_RECEIVED);
LocalBroadcastManager.getInstance(MyApplication.getContext()).sendBroadcast(intent);
if(error != null && error.getMessage() != null) {
// Toast.makeText(MyApplication.getContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
else {
Log.i(TAG, "postRequestToServer: onErrorResponse : error message null");
}
}
};
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, url, rListner, errorListner)
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
// #Override
// public Map<String, String> getHeaders() throws AuthFailureError {
// return params;
// }
#Override
public String getBodyContentType() {
return mHttpEntity.build().getContentType().getValue();
}
//
#Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mHttpEntity.build().writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
};
private MultipartEntityBuilder buildMultipartEntity(String files_to_upload, HashMap<String, String> params) {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
String[] arr_files = files_to_upload.split("##");
for(int i = 0; i < arr_files.length; i++) {
String filePath = arr_files[i];
if(filePath == null || filePath.length() == 0)
continue;
File file = new File(filePath);
String extension = MimeTypeMap.getFileExtensionFromUrl(arr_files[i]);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
builder.addBinaryBody("userfile", file, ContentType.create(mimeType), file.getName());
// builder.addPart("userfile", new FileBody(file));
}
try {
for (String key: params.keySet())
builder.addPart(key, new StringBody(params.get(key)));
} catch (UnsupportedEncodingException e) {
VolleyLog.e("UnsupportedEncodingException");
}
return builder;
}
But the issue is getParams is not being called. Server is expecting paramters, I tried to send using EntityBuilder but still I am having errors in sending the parameters.
Can anyone please let me know how can I upload files using
StringRequest with Parameters?
Your getParams() is not getting called because StringRequest.java inherits from Request.java. Now in Request.java, if you look at the getBody() method,
public byte[] getBody() throws AuthFailureError {
Map<String, String> params = getParams();
if (params != null && params.size() > 0) {
return encodeParameters(params, getParamsEncoding());
}
return null;
}
you can see getParams() is getting called from getBody() method. Now while making your request StringRequest jsonObjectRequest, you are overriding the getBody() method which means your getParams() will not get called. This is the reason why getParams() is not getting called.
EDIT
Create this custom volley request class that takes params inside the request constructor
public class CustomRequest extends Request<String> {
private Listener<String> listener;
private Map<String, String> params;
public CustomRequest(int method, String url, Map<String, String> params,
Listener<String> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
};
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(jsonString, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(String response) {
listener.onResponse(response);
}
}
Now send your request through this class. instead of overriding getParams(), just create a hashmap for your params, and pass them inside the constructor.
Use getparams and getHeader metods:
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("product_id", "4");
parameters.put("count", Productcount.getText().toString());
parameters.put("type", cashstatus);
parameters.put("description", "Matn bo'ladi");
parameters.put("phone_number", "946287009");
parameters.put("on_map", address);
return parameters;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", "Bearer " + token);
return headers;
}
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.