Hi I know voley call sending parameter using Map
for ex
private void SignInWithEmail() {
//email= String.valueOf(mEmail.getText());
//pass = String.valueOf(mPassword.getText());
String url = RequestUrls.getInstance().signInByEmail();
StringRequest mRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.v(TAG, "Login with email" + response);
try {
JSONObject jsonResponse = new JSONObject(response);
String code = jsonResponse.getString("code");
if (code == "1") {
JSONArray UserDetailArray = jsonResponse.getJSONArray("document");
Log.v("Login with email", UserDetailArray.toString());
JSONObject finalObject = UserDetailArray.getJSONObject(0);
String User_email = finalObject.getString("Email");
getUserByEmail(User_email);
} else {
Toast.makeText(getApplicationContext(), "Invalid Email or Password", Toast.LENGTH_SHORT).show();
mPassword.setText("");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.v(TAG, "Request for getUserByEmail Error: " + error.toString());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Action", "GetUserByEmail");
//Log.v("Login", "Action Email for put: " + email);
params.put("UserName", email);
params.put("Password", pass);
return params;
}
};
VolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(mRequest);
}
but i have to send
this as parameter how to do that
{
"jsonrpc": "2.0",
"method": "signUp",
"id": "1",
"params": {
"email": "abc#gmail.com",
"fname": "abc",
"lname": "def",
"pwd": "123"
}
}
do i have to add header or any other method please suggest me.I am new in android development.
this the screen shot from postman chrome extension
please help me.
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.POST, url, json, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
you can send your json using the above code in the json paramter.
try
JSONObject jsonObject1 = new JSONObject();
try {
jsonObject1.put("email", "abc#gmail.com");
jsonObject1.put("fname", "abc");
jsonObject1.put("lname", "def");
jsonObject1.put("pwd", "123");
} catch (JSONException e) {
e.printStackTrace();
}
Map<String, String> postParam = new HashMap<>();
postParam.put("jsonrpc", "2.0");
postParam.put("method", "signUp");
postParam.put("id", "1");
postParam.put("params", jsonObject1.toString());
CustomRequest jsObjRequest = new CustomRequest(
Request.Method.POST,
URL,
postParam, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError arg0) {
}
});
mRequestQueue.add(jsObjRequest);
Happy code
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(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) {
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);
}
}
Use CustomRequest and pass your map in the argument.
Steps to Send Object/Model/POJO class to volley post request.
Step 1: Make sure your class should the parsable.
Step 2: Override the toString method in model class.
Step 3: Create map i.e Map<String, Object> params = new Map<String, Object>
();
JSONObject object = new JSONObject(classObject.toString())
params.put("key", object)
Step 4: Put the params with volley request.
Related
I saw Google IO 2013 session about Volley and I'm considering switching to volley. Does Volley support adding POST/GET parameters to request? If yes, how can I do it?
For the GET parameters there are two alternatives:
First: As suggested in a comment bellow the question you can just use String and replace the parameters placeholders with their values like:
String uri = String.format("http://somesite.com/some_endpoint.php?param1=%1$s¶m2=%2$s",
num1,
num2);
StringRequest myReq = new StringRequest(Method.GET,
uri,
createMyReqSuccessListener(),
createMyReqErrorListener());
queue.add(myReq);
where num1 and num2 are String variables that contain your values.
Second: If you are using newer external HttpClient (4.2.x for example) you can use URIBuilder to build your Uri. Advantage is that if your uri string already has parameters in it it will be easier to pass it to the URIBuilder and then use ub.setQuery(URLEncodedUtils.format(getGetParams(), "UTF-8")); to add your additional parameters. That way you will not bother to check if "?" is already added to the uri or to miss some & thus eliminating a source for potential errors.
For the POST parameters probably sometimes will be easier than the accepted answer to do it like:
StringRequest myReq = new StringRequest(Method.POST,
"http://somesite.com/some_endpoint.php",
createMyReqSuccessListener(),
createMyReqErrorListener()) {
protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("param1", num1);
params.put("param2", num2);
return params;
};
};
queue.add(myReq);
e.g. to just override the getParams() method.
You can find a working example (along with many other basic Volley examples) in the Andorid Volley Examples project.
In your Request class (that extends Request), override the getParams() method. You would do the same for headers, just override getHeaders().
If you look at PostWithBody class in TestRequest.java in Volley tests, you'll find an example.
It goes something like this
public class LoginRequest extends Request<String> {
// ... other methods go here
private Map<String, String> mParams;
public LoginRequest(String param1, String param2, Listener<String> listener, ErrorListener errorListener) {
super(Method.POST, "http://test.url", errorListener);
mListener = listener;
mParams = new HashMap<String, String>();
mParams.put("paramOne", param1);
mParams.put("paramTwo", param2);
}
#Override
public Map<String, String> getParams() {
return mParams;
}
}
Evan Charlton was kind enough to make a quick example project to show us how to use volley.
https://github.com/evancharlton/folly/
CustomRequest is a way to solve the Volley's JSONObjectRequest can't post parameters like the StringRequest
here is the helper class which allow to add params:
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(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) {
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);
}
}
thanks to Greenchiu
This helper class manages parameters for GET and POST requests:
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private int mMethod;
private String mUrl;
private Map<String, String> mParams;
private Listener<JSONObject> mListener;
public CustomRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.mMethod = method;
this.mUrl = url;
this.mParams = params;
this.mListener = reponseListener;
}
#Override
public String getUrl() {
if(mMethod == Request.Method.GET) {
if(mParams != null) {
StringBuilder stringBuilder = new StringBuilder(mUrl);
Iterator<Map.Entry<String, String>> iterator = mParams.entrySet().iterator();
int i = 1;
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (i == 1) {
stringBuilder.append("?" + entry.getKey() + "=" + entry.getValue());
} else {
stringBuilder.append("&" + entry.getKey() + "=" + entry.getValue());
}
iterator.remove(); // avoids a ConcurrentModificationException
i++;
}
mUrl = stringBuilder.toString();
}
}
return mUrl;
}
#Override
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return mParams;
};
#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) {
// TODO Auto-generated method stub
mListener.onResponse(response);
}
}
Dealing with GET parameters I iterated on Andrea Motto' solution.
The problem was that Volley called GetUrl several times and his solution, using an Iterator, destroyed original Map object. The subsequent Volley internal calls had an empty params object.
I added also the encode of parameters.
This is an inline usage (no subclass).
public void GET(String url, Map<String, String> params, Response.Listener<String> response_listener, Response.ErrorListener error_listener, String API_KEY, String stringRequestTag) {
final Map<String, String> mParams = params;
final String mAPI_KEY = API_KEY;
final String mUrl = url;
StringRequest stringRequest = new StringRequest(
Request.Method.GET,
mUrl,
response_listener,
error_listener
) {
#Override
protected Map<String, String> getParams() {
return mParams;
}
#Override
public String getUrl() {
StringBuilder stringBuilder = new StringBuilder(mUrl);
int i = 1;
for (Map.Entry<String,String> entry: mParams.entrySet()) {
String key;
String value;
try {
key = URLEncoder.encode(entry.getKey(), "UTF-8");
value = URLEncoder.encode(entry.getValue(), "UTF-8");
if(i == 1) {
stringBuilder.append("?" + key + "=" + value);
} else {
stringBuilder.append("&" + key + "=" + value);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
i++;
}
String url = stringBuilder.toString();
return url;
}
#Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<>();
if (!(mAPI_KEY.equals(""))) {
headers.put("X-API-KEY", mAPI_KEY);
}
return headers;
}
};
if (stringRequestTag != null) {
stringRequest.setTag(stringRequestTag);
}
mRequestQueue.add(stringRequest);
}
This function uses headers to pass an APIKEY and sets a TAG to the request useful to cancel it before its completion.
Hope this helps.
This may help you...
private void loggedInToMainPage(final String emailName, final String passwordName) {
String tag_string_req = "req_login";
StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://localhost/index", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Login Response: " + response.toString());
try {
JSONObject jsonObject = new JSONObject(response);
Boolean error = jsonObject.getBoolean("error");
if (!error) {
String uid = jsonObject.getString("uid");
JSONObject user = jsonObject.getJSONObject("user");
String email = user.getString("email");
String password = user.getString("password");
session.setLogin(true);
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
Toast.makeText(getApplicationContext(), "its ok", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println("volley Error .................");
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "login");
params.put("email", emailName);
params.put("password", passwordName);
return params;
}
};
MyApplication.getInstance().addToRequestQueue(stringRequest,tag_string_req);
}
For Future Readers
I love to work with Volley. To save development time i tried to write small handy library Gloxey Netwok Manager to setup Volley with my project. It includes JSON parser and different other methods that helps to check network availability.
Use ConnectionManager.class in which different methods for Volley String and Volley JSON request are available.
You can make requests of GET, PUT, POST, DELETE with or without header. You can read full documentation here.
Just put this line in your gradle file.
dependencies {
compile 'io.gloxey.gnm:network-manager:1.0.1'
}
Volley StringRequest
Method GET (without header)
ConnectionManager.volleyStringRequest(context, isDialog, progressDialogView, requestURL, volleyResponseInterface);
How to use?
Configuration Description
Context Context
isDialog If true dialog will appear, otherwise not.
progressView For custom progress view supply your progress view id and make isDialog true. otherwise pass null.
requestURL Pass your API URL.
volleyResponseInterface Callback for response.
Example
ConnectionManager.volleyStringRequest(this, false, null, "url", new VolleyResponse() {
#Override
public void onResponse(String _response) {
/**
* Handle Response
*/
}
#Override
public void onErrorResponse(VolleyError error) {
/**
* handle Volley Error
*/
}
#Override
public void isNetwork(boolean connected) {
/**
* True if internet is connected otherwise false
*/
}
});
Volley StringRequest
Method POST/PUT/DELETE (without header)
ConnectionManager.volleyStringRequest(context, isDialog, progressDialogView, requestURL, requestMethod, params, volleyResponseInterface);
Example
Use Method : Request.Method.POST
Request.Method.PUT
Request.Method.DELETE
Your params :
HashMap<String, String> params = new HashMap<>();
params.put("param 1", "value");
params.put("param 2", "value");
ConnectionManager.volleyStringRequest(this, true, null, "url", Request.Method.POST, params, new VolleyResponse() {
#Override
public void onResponse(String _response) {
/**
* Handle Response
*/
}
#Override
public void onErrorResponse(VolleyError error) {
/**
* handle Volley Error
*/
}
#Override
public void isNetwork(boolean connected) {
/**
* True if internet is connected otherwise false
*/
}
});
Bonus
Gloxey JSON Parser
Feel free to use gloxey json parser to parse your api response.
YourModel yourModel = GloxeyJsonParser.getInstance().parse(stringResponse, YourModel.class);
Example
ConnectionManager.volleyStringRequest(this, false, null, "url", new VolleyResponse() {
#Override
public void onResponse(String _response) {
/**
* Handle Response
*/
try {
YourModel yourModel = GloxeyJsonParser.getInstance().parse(_response, YourModel.class);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onErrorResponse(VolleyError error) {
/**
* handle Volley Error
*/
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
showSnackBar(parentLayout, getString(R.string.internet_not_found), getString(R.string.retry), new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle retry button
}
});
} else if (error instanceof AuthFailureError) {
} else if (error instanceof ServerError) {
} else if (error instanceof NetworkError) {
} else if (error instanceof ParseError) {
}
}
#Override
public void isNetwork(boolean connected) {
/**
* True if internet is connected otherwise false
*/
if (!connected) {
showSnackBar(parentLayout, getString(R.string.internet_not_found), getString(R.string.retry), new View.OnClickListener() {
#Override
public void onClick(View view) {
//Handle retry button
}
});
}
});
public void showSnackBar(View view, String message) {
Snackbar.make(view, message, Snackbar.LENGTH_LONG).show();
}
public void showSnackBar(View view, String message, String actionText, View.OnClickListener onClickListener) {
Snackbar.make(view, message, Snackbar.LENGTH_LONG).setAction(actionText, onClickListener).show();
}
To provide POST parameter send your parameter as JSONObject in to the JsonObjectRequest constructor. 3rd parameter accepts a JSONObject that is used in Request body.
JSONObject paramJson = new JSONObject();
paramJson.put("key1", "value1");
paramJson.put("key2", "value2");
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,url,paramJson,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(jsonObjectRequest);
i am struggling to make this work, basically i get an id from previous activity using intent, now i want to send this id to server so it returns all the data associated with this id.
javacode
final String URL = "URL";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("ID", "1");
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
print response in textview;
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
PHP server
if (!empty($_POST)) {
$query = " SELECT * FROM table WHERE ID = :ID " ;
$query_params = array(
':ID' => $_POST['ID'],);
try {
$statement = $db->prepare($query);
$result = $statement->execute($query_params);
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Database query error";
die(json_encode($response));
}
$result = $statement->fetchAll();
if($result){
$data =array();
foreach($result as $rows){
$json = array();
$json["Name"] = $rows["Name"];
array_push ($data,$json);
}
echo stripcslashes(json_encode($data, JSON_PRETTY_PRINT));
i used this example of http://www.itsalif.info/content/android-volley-tutorial-http-get-post-put and coverted the string response to string array, worked for me
url = "http://httpbin.org/post";
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
Log.d("Response", response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", response);
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("name", "Alif");
params.put("domain", "http://itsalif.info");
return params;
}
};
queue.add(postRequest);
I would modify the request like this:
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,URL,null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
print response in textview;
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
})
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("ID", "1");
return params;
}
};
ApplicationController.getInstance().addToRequestQueue(req);
and also would modify the PHP code like this:
if (isset($_POST['ID'])) {
$id = $_POST['ID'];
try {
$statement = $db->prepare(SELECT * FROM table WHERE ID = ?);
$statement->bindValue(1, $id);
$result = $statement->execute();
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Database query error";
die(json_encode($response));
}
$records = array();
$records = $statement->fetchAll(PDO::FETCH_ASSOC);
$data = array();
foreach($records as $record){
$data["Name"] = $record["Name"];
}
echo stripcslashes(json_encode($data, JSON_PRETTY_PRINT));
}
Hope it helps!!!
the issue is that you send json but you expect params in you php.
there 2 solutions:
1) update php to accept json not just post params
2) update volley request to send post params but expect JSONObject
for example you can use this request:
public class JsonObjReq extends Request<JSONObject> {
private final Response.Listener<JSONObject> mListener;
private final Map<String, String> params;
public JsonObjReq(int method, String url, Map<String, String> params, Response
.Listener<JSONObject> mListener,
Response.ErrorListener listener) {
super(method, url, listener);
this.mListener = mListener;
this.params = params;
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, "utf-8"));
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) {
mListener.onResponse(response);
}
}
and apply to your code like that:
final String URL = "URL";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("ID", "1");
JsonObjReq req = new JsonObjReq(Method.POST, URL, params,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
print response in textview;
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
I'm trying to post an JSONObject using Volley. Most probably, the servers response is not type JSONObject. Any ideas or workaround?
This is my code:
RequestQueue requestQueue = Volley.newRequestQueue(context);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, jsonobject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Build.logError("Response:" + response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Build.logError("Error: " + volleyError);
}
});
requestQueue.add(jsonObjectRequest);
and this is the error response I'm receiving :
com.android.volley.ParseError: org.json.JSONException: Value OK of type java.lang.String cannot be converted to JSONObject
Thank you in advance.
Here's what I did using String request. In this example, I'm posting parameters inside JSON object.
Tested it out using http://posttestserver.com/post.php. Basically override two POST related methods of the super class (Request class) getBody() and getBodyContentType() to supply post data.
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
final JSONObject jsonObject = new JSONObject();
jsonObject.put("fName", "First");
jsonObject.put("lName", "Last");
jsonObject.put("age", 11);
jsonObject.put("ts", System.currentTimeMillis());
StringRequest stringRequest = new StringRequest(Request.Method.POST, uri,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println("Response from server: " + response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
if (response != null) {
System.out.println("error code: " + response.statusCode);
}
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
return jsonObject.toString().getBytes();
}
#Override
public String getBodyContentType() {
return "application/json";
}
};
You have to write custom request.. please try below one
import java.io.UnsupportedEncodingException;
import java.util.Map;
import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.RetryPolicy;
import com.android.volley.toolbox.HttpHeaderParser;
public class ServerStatusRequestObject extends Request<String> {
private final Response.Listener mListener;
private String mBody;
private String mContentType;
private HashMap mCustomHeaders;
public ServerStatusRequestObject(int method, String url,
HashMap customHeaders, String body, Response.Listener listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
mCustomHeaders = customHeaders;
mBody = body;
mListener = listener;
mContentType = "application/json";
if (method == Method.POST) {
RetryPolicy policy = new DefaultRetryPolicy(5000, 0, 5);
setRetryPolicy(policy);
}
}
public ServerStatusRequestObject(String url, HashMap customHeaders,
Response.Listener listener, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
mCustomHeaders = customHeaders;
mListener = listener;
mContentType = "application/x-www-form-urlencoded";
}
#Override
protected Response parseNetworkResponse(NetworkResponse response) {
String json = null;
try {
json = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Response.success(json,
HttpHeaderParser.parseCacheHeaders(response));
}
#Override
public Map getHeaders() throws AuthFailureError {
if (mCustomHeaders != null) {
return mCustomHeaders;
}
return super.getHeaders();
}
#Override
public byte[] getBody() throws AuthFailureError {
return mBody.getBytes();
}
#Override
public String getBodyContentType() {
return mContentType;
}
public String getContentType() {
return mContentType;
}
public void setContentType(String mContentType) {
this.mContentType = mContentType;
}
#Override
protected void deliverResponse(String arg0) {
// TODO Auto-generated method stub
mListener.onResponse(arg0);
}
}
use like this
ServerStatusRequestObject jsonObjReq = new ServerStatusRequestObject(
Method.POST, Urls.logout, headers, json.toString(),
new Response.Listener<String>() {
#Override
public void onResponse(String arg0) {
// TODO Auto-generated method stub
Common.stopProgressDialog();
System.out.println("string response = " + arg0);
Toast.makeText(MainActivity.this, "Logout success",
Toast.LENGTH_LONG).show();
Common.savePref(MainActivity.this, Constants.sessionId,
null);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
Common.stopProgressDialog();
System.out.println("error = " + arg0);
}
});
I was trying to make a POST request through Volley. It is working totally fine in my localhost but when i moved it to webserver the response is empty.
Java Code
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest sr = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.dismiss();
Log.d("Response: ", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error: ", error + "");
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("name", name);
params.put("phone", phone);
params.put("email", email);
Log.d("getParams", params.toString());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
Log.d("getHeaders", params.toString());
return params;
}
};
queue.add(sr);
PHP Code
$name = $this->input->post('name');
$phone = $this->input->post('phone');
$email = $this->input->post('email');
echo "Name: ".$name." Phone: ".$phone." Email:".$email;
I had faced same problem previously and fixed by using custom request queue.
first create custom request class CustomRequest.java
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(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) {
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);
}
}
Then i performed request as this
Map<String, String> params = new HashMap<String, String>();
params.put("name", name);
params.put("email", phone);
params.put("phone", email);
CustomRequest jsonObjReq = new CustomRequest(
Method.POST,
Const.URL_SEND_FEEDBACK,params,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}) {
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
//params.put("Content-Type", "application/x-www-form-urlencoded"); not used this
Log.d("getHeaders", params.toString());
return params;
}
};
AppController.getInstance().addToRequestQueue(jsonObjReq);
Try adding charset=utf-8 to it. After much searching, that was what worked for me.
Credit: http://envyandroid.com/android-volley-empty-parameters/
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest sr = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.dismiss();
Log.d("Response: ", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error: ", error + "");
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("name", name);
params.put("phone", phone);
params.put("email", email);
Log.d("getParams", params.toString());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
Log.d("getHeaders", params.toString());
return params;
}
};
queue.add(sr);
I saw Google IO 2013 session about Volley and I'm considering switching to volley. Does Volley support adding POST/GET parameters to request? If yes, how can I do it?
For the GET parameters there are two alternatives:
First: As suggested in a comment bellow the question you can just use String and replace the parameters placeholders with their values like:
String uri = String.format("http://somesite.com/some_endpoint.php?param1=%1$s¶m2=%2$s",
num1,
num2);
StringRequest myReq = new StringRequest(Method.GET,
uri,
createMyReqSuccessListener(),
createMyReqErrorListener());
queue.add(myReq);
where num1 and num2 are String variables that contain your values.
Second: If you are using newer external HttpClient (4.2.x for example) you can use URIBuilder to build your Uri. Advantage is that if your uri string already has parameters in it it will be easier to pass it to the URIBuilder and then use ub.setQuery(URLEncodedUtils.format(getGetParams(), "UTF-8")); to add your additional parameters. That way you will not bother to check if "?" is already added to the uri or to miss some & thus eliminating a source for potential errors.
For the POST parameters probably sometimes will be easier than the accepted answer to do it like:
StringRequest myReq = new StringRequest(Method.POST,
"http://somesite.com/some_endpoint.php",
createMyReqSuccessListener(),
createMyReqErrorListener()) {
protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("param1", num1);
params.put("param2", num2);
return params;
};
};
queue.add(myReq);
e.g. to just override the getParams() method.
You can find a working example (along with many other basic Volley examples) in the Andorid Volley Examples project.
In your Request class (that extends Request), override the getParams() method. You would do the same for headers, just override getHeaders().
If you look at PostWithBody class in TestRequest.java in Volley tests, you'll find an example.
It goes something like this
public class LoginRequest extends Request<String> {
// ... other methods go here
private Map<String, String> mParams;
public LoginRequest(String param1, String param2, Listener<String> listener, ErrorListener errorListener) {
super(Method.POST, "http://test.url", errorListener);
mListener = listener;
mParams = new HashMap<String, String>();
mParams.put("paramOne", param1);
mParams.put("paramTwo", param2);
}
#Override
public Map<String, String> getParams() {
return mParams;
}
}
Evan Charlton was kind enough to make a quick example project to show us how to use volley.
https://github.com/evancharlton/folly/
CustomRequest is a way to solve the Volley's JSONObjectRequest can't post parameters like the StringRequest
here is the helper class which allow to add params:
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(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) {
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);
}
}
thanks to Greenchiu
This helper class manages parameters for GET and POST requests:
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private int mMethod;
private String mUrl;
private Map<String, String> mParams;
private Listener<JSONObject> mListener;
public CustomRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.mMethod = method;
this.mUrl = url;
this.mParams = params;
this.mListener = reponseListener;
}
#Override
public String getUrl() {
if(mMethod == Request.Method.GET) {
if(mParams != null) {
StringBuilder stringBuilder = new StringBuilder(mUrl);
Iterator<Map.Entry<String, String>> iterator = mParams.entrySet().iterator();
int i = 1;
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (i == 1) {
stringBuilder.append("?" + entry.getKey() + "=" + entry.getValue());
} else {
stringBuilder.append("&" + entry.getKey() + "=" + entry.getValue());
}
iterator.remove(); // avoids a ConcurrentModificationException
i++;
}
mUrl = stringBuilder.toString();
}
}
return mUrl;
}
#Override
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return mParams;
};
#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) {
// TODO Auto-generated method stub
mListener.onResponse(response);
}
}
Dealing with GET parameters I iterated on Andrea Motto' solution.
The problem was that Volley called GetUrl several times and his solution, using an Iterator, destroyed original Map object. The subsequent Volley internal calls had an empty params object.
I added also the encode of parameters.
This is an inline usage (no subclass).
public void GET(String url, Map<String, String> params, Response.Listener<String> response_listener, Response.ErrorListener error_listener, String API_KEY, String stringRequestTag) {
final Map<String, String> mParams = params;
final String mAPI_KEY = API_KEY;
final String mUrl = url;
StringRequest stringRequest = new StringRequest(
Request.Method.GET,
mUrl,
response_listener,
error_listener
) {
#Override
protected Map<String, String> getParams() {
return mParams;
}
#Override
public String getUrl() {
StringBuilder stringBuilder = new StringBuilder(mUrl);
int i = 1;
for (Map.Entry<String,String> entry: mParams.entrySet()) {
String key;
String value;
try {
key = URLEncoder.encode(entry.getKey(), "UTF-8");
value = URLEncoder.encode(entry.getValue(), "UTF-8");
if(i == 1) {
stringBuilder.append("?" + key + "=" + value);
} else {
stringBuilder.append("&" + key + "=" + value);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
i++;
}
String url = stringBuilder.toString();
return url;
}
#Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<>();
if (!(mAPI_KEY.equals(""))) {
headers.put("X-API-KEY", mAPI_KEY);
}
return headers;
}
};
if (stringRequestTag != null) {
stringRequest.setTag(stringRequestTag);
}
mRequestQueue.add(stringRequest);
}
This function uses headers to pass an APIKEY and sets a TAG to the request useful to cancel it before its completion.
Hope this helps.
This may help you...
private void loggedInToMainPage(final String emailName, final String passwordName) {
String tag_string_req = "req_login";
StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://localhost/index", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Login Response: " + response.toString());
try {
JSONObject jsonObject = new JSONObject(response);
Boolean error = jsonObject.getBoolean("error");
if (!error) {
String uid = jsonObject.getString("uid");
JSONObject user = jsonObject.getJSONObject("user");
String email = user.getString("email");
String password = user.getString("password");
session.setLogin(true);
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
Toast.makeText(getApplicationContext(), "its ok", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println("volley Error .................");
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "login");
params.put("email", emailName);
params.put("password", passwordName);
return params;
}
};
MyApplication.getInstance().addToRequestQueue(stringRequest,tag_string_req);
}
For Future Readers
I love to work with Volley. To save development time i tried to write small handy library Gloxey Netwok Manager to setup Volley with my project. It includes JSON parser and different other methods that helps to check network availability.
Use ConnectionManager.class in which different methods for Volley String and Volley JSON request are available.
You can make requests of GET, PUT, POST, DELETE with or without header. You can read full documentation here.
Just put this line in your gradle file.
dependencies {
compile 'io.gloxey.gnm:network-manager:1.0.1'
}
Volley StringRequest
Method GET (without header)
ConnectionManager.volleyStringRequest(context, isDialog, progressDialogView, requestURL, volleyResponseInterface);
How to use?
Configuration Description
Context Context
isDialog If true dialog will appear, otherwise not.
progressView For custom progress view supply your progress view id and make isDialog true. otherwise pass null.
requestURL Pass your API URL.
volleyResponseInterface Callback for response.
Example
ConnectionManager.volleyStringRequest(this, false, null, "url", new VolleyResponse() {
#Override
public void onResponse(String _response) {
/**
* Handle Response
*/
}
#Override
public void onErrorResponse(VolleyError error) {
/**
* handle Volley Error
*/
}
#Override
public void isNetwork(boolean connected) {
/**
* True if internet is connected otherwise false
*/
}
});
Volley StringRequest
Method POST/PUT/DELETE (without header)
ConnectionManager.volleyStringRequest(context, isDialog, progressDialogView, requestURL, requestMethod, params, volleyResponseInterface);
Example
Use Method : Request.Method.POST
Request.Method.PUT
Request.Method.DELETE
Your params :
HashMap<String, String> params = new HashMap<>();
params.put("param 1", "value");
params.put("param 2", "value");
ConnectionManager.volleyStringRequest(this, true, null, "url", Request.Method.POST, params, new VolleyResponse() {
#Override
public void onResponse(String _response) {
/**
* Handle Response
*/
}
#Override
public void onErrorResponse(VolleyError error) {
/**
* handle Volley Error
*/
}
#Override
public void isNetwork(boolean connected) {
/**
* True if internet is connected otherwise false
*/
}
});
Bonus
Gloxey JSON Parser
Feel free to use gloxey json parser to parse your api response.
YourModel yourModel = GloxeyJsonParser.getInstance().parse(stringResponse, YourModel.class);
Example
ConnectionManager.volleyStringRequest(this, false, null, "url", new VolleyResponse() {
#Override
public void onResponse(String _response) {
/**
* Handle Response
*/
try {
YourModel yourModel = GloxeyJsonParser.getInstance().parse(_response, YourModel.class);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onErrorResponse(VolleyError error) {
/**
* handle Volley Error
*/
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
showSnackBar(parentLayout, getString(R.string.internet_not_found), getString(R.string.retry), new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle retry button
}
});
} else if (error instanceof AuthFailureError) {
} else if (error instanceof ServerError) {
} else if (error instanceof NetworkError) {
} else if (error instanceof ParseError) {
}
}
#Override
public void isNetwork(boolean connected) {
/**
* True if internet is connected otherwise false
*/
if (!connected) {
showSnackBar(parentLayout, getString(R.string.internet_not_found), getString(R.string.retry), new View.OnClickListener() {
#Override
public void onClick(View view) {
//Handle retry button
}
});
}
});
public void showSnackBar(View view, String message) {
Snackbar.make(view, message, Snackbar.LENGTH_LONG).show();
}
public void showSnackBar(View view, String message, String actionText, View.OnClickListener onClickListener) {
Snackbar.make(view, message, Snackbar.LENGTH_LONG).setAction(actionText, onClickListener).show();
}
To provide POST parameter send your parameter as JSONObject in to the JsonObjectRequest constructor. 3rd parameter accepts a JSONObject that is used in Request body.
JSONObject paramJson = new JSONObject();
paramJson.put("key1", "value1");
paramJson.put("key2", "value2");
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,url,paramJson,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(jsonObjectRequest);