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;
}
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
Android volley library is not accepting parameters from getParam() method.If it is given in query String then it works.I tried both GET and POST it doesn't works. But I want to give parameters POST Method.please check the code I have posted below.
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url = AppConstants.WEBSERVICE_URL
+ AppConstants.WEBSERVICE_URL_POST_COMMENT;
StringRequest getRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// response
Log.d("Response_postComment", response);
Intent intent = new Intent(getApplicationContext(),
ReviewActivity.class);
intent.putExtra("serviceId", servicePosition);
startActivity(intent);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", 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() throws AuthFailureError{
Map<String, String> params = new HashMap<String, String>();
params.put("rating", ratingBar.getRating() + "");
params.put("com_content", comments.getText() + "");
params.put("user_id", AppConstants.APP_LOGIN_USER_ID);
params.put("comm_post_ID", AppConstants.arrListServiceDetail
.get(servicePosition).getId() + "");
return params;
}
};
getRequest.setRetryPolicy(new DefaultRetryPolicy(500000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(getRequest);
getParam() method not working with GET request on volley.its working fine with POST methods.you have to set up complete URL with parameters.
I faced the same issue as you are facing now, but comes up with solution of making a custom request by making the core class Request as the super class of this request. In this i am passing params in constructor, then returning it to the getParams() overridden method as below:
public class RequestJson extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public RequestJson(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public RequestJson(int method, String url, Map<String, String> params,
Listener<JSONObject> 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<JSONObject> parseNetworkResponse(NetworkResponse response) {
AppController.getInstance().checkSessionCookie(response.headers);
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(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(JSONObject response) {
// TODO Auto-generated method stub
listener.onResponse(response);
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
AppController.getInstance().addSessionCookie(headers);
return headers;
}
}
Hope this will solve your problem.
I start using Volley for my application and I want to add custom headers for each request as a security identifier.
I'm using a JsonObjectRequest and overriding the getHeaders().
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
String mApiKey = "123";
headers.put("APIKEY", mApiKey);
return headers;
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("param1", "1");
params.put("param2", "2");
params.put("param3", "3");
return params;
}
};
VolleySingleton.getInstance(getActivity()).addToRequestQueue(jsonObjectRequest);
But I get this error:
E/Volley﹕ [23620] BasicNetwork.performRequest: Unexpected response code 401 for http://...
The AuthFailureError is thrown.
I also try to use StringRequest but same error.
If someone is in the same case and have solution, thank you in advance!
This is a basic concept how to override a header in a standard VolleyRequest
VolleyRequest networkRequest = new VolleyRequest(request.getHttpMethod(), mUrlBase + request.getUrlSuffix(), responseListener, errorListener) {
public String getBodyContentType() {
return "application/json; charset=" + getParamsEncoding();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> map = new HashMap<String, String>();
map.put("X-Device-Info","Android FOO BAR");
map.put("Accept-Language", acceptLanguage);
map.put("Content-Type", "application/json; charset=UTF-8");
return map;
}
public byte[] getBody() throws AuthFailureError {
try {
String json = request.toJson().toString();
if (json.length() < 3)
return ("{}").getBytes();
// log(json);
return json.getBytes(getParamsEncoding());
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "getBody(): request has no json");
e.printStackTrace();
}
return new byte[0];
}
};
public class CustomJsonObjectRequest extends JsonObjectRequest
{
public CustomJsonObjectRequest(int method, String url, JSONObject jsonRequest,Response.Listener listener, Response.ErrorListener errorListener)
{
super(method, url, jsonRequest, listener, errorListener);
}
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put(Constants.accesstoken, Globals.getInstance().getAccessToken());
Logger.debugE(Constants.accesstoken, headers.toString());
return headers;
}
}
I am trying create a custom BasicAuthentication with Volley. I have a class ApplicationController that I implemented methods getHeaders and works fine with all application, but now, I have a method that I need send other BasicAuthentication with other Parameters. To do it I am trying #Override the getHeaders() of class ApplicationController. It doesnt works and return a exception.
How can I do it ?
Exception
12-13 20:11:26.300 32356-430/br.com.application.apppackage E/Volley﹕ [157735] BasicNetwork.performRequest: Unexpected response code 400 for http://www.aplication.com.br/ServiceEndpointRest/WsChat/ws/salas/interact.json
12-13 20:11:26.305 32356-32356/br.com.application.apppackage E/ERROR METHOD:﹕ receiveMessage in ChatDAO: null
I'm trying this.
ApplicationController
public class ApplicationController extends Request<JSONObject>{
private Map<String, String> headers;
private Map<String, String> params;
private Response.Listener<JSONObject> listener;
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
private File mImageFile;
private Map<String, Object> imageParams;
public ApplicationController(String url, Map<String, String> params, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = listener;
this.params = params;
}
public ApplicationController(int method, String url, Map<String, String> params, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = listener;
this.params = params;
}
protected Map<String, String> getParams() throws AuthFailureError {
return params;
};
public Map<String, String> getHeaders() throws AuthFailureError {
headers = new HashMap<String, String>();
String cred = String.format("%s:%s", BasicAuthenticationRest.USERNAME, BasicAuthenticationRest.PASSWORD);
String auth = "Basic " + Base64.encodeToString(cred.getBytes(), Base64.DEFAULT);
headers.put("Authorization", auth);
return headers;
};
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(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(JSONObject response) {
listener.onResponse(response);
}
}
#Override Header in Method receiveMessage
public ApplicationController receiveMessage(String emailAdversario){
///{\"Sala\":{\"usuario\":\"%#\",\"adversario\":\"%#\",\"atualizacao\":\"%#\",\"device\":\"%#\",\"device_tipo\":\"ios\"}}
urlPost.append("WsChat/ws/salas/interacao.json");
HashMap<String, String> params = new HashMap<String, String>();
params.put("usuario", BatalhaConfigs.USUARIO_EMAIL);
params.put("atualizacao", new Date().toString());
params.put("email", BatalhaConfigs.USUARIO_EMAIL);
params.put("device", AndroidReturnId.getAndroidId());
params.put("device_tipo", "android");
ApplicationController apc = new ApplicationController(Request.Method.POST,
urlPost.toString(),
params,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject obj) {
Log.i("RESPOSTA DA MENSAGEM: ", obj.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError arg0) {
Log.e("ERROR METHOD:", "receiveMessage in ChatDAO: " + arg0.getLocalizedMessage());
}
})
{
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
String cred = String.format("%s:%s", BatalhaConfigs.USUARIO_EMAIL, BatalhaConfigs.USUARIO_SENHA);
String auth = "Basic " + Base64.encodeToString(cred.getBytes(), Base64.DEFAULT);
headers.put("Authorization", auth);
return headers;
}};
return apc;
}