I'm trying to make a POST request to get token from my web API (writen by asp.net mvc) and it works in Postman (I get a valid JSON object), but not using Volley. With the following code:
String url = "https://branj.ir/Token";
Response.Listener<String> listener= new Response.Listener<String>() {
#Override
public void onResponse(String jsonResult) {
Log.i(G.Tag, "volley result: " + jsonResult);
}
};
Response.ErrorListener errorListener= new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.d(G.Tag, "Error: " + error
+ "\nStatus Code " + error.networkResponse.statusCode
+ "\nCause " + error.getCause()
+ "\nmessage" + error.getMessage());
}
};
StringRequest request = new StringRequest (
Request.Method.POST,
url,
listener,
errorListener
)
{
#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");
params.put("Accept", "application/json");
return params;
} }
;
logcat is:
BasicNetwork.performRequest: Unexpected response code 400 for https://branj.ir/Token
11-13 16:55:59.608 21200-21200/ir.branj.app.wideidea.ir.branj D/Branj: Error: com.android.volley.ClientError
Status Code 400
Cause null
messagenull
I changed the application code as follows and my problem was resolved
public static void Token(final String username, final String password) {
String url = BASE_URL + "Token";
Response.Listener<String> listener= new Response.Listener<String>() {
#Override
public void onResponse(String jsonResult) {
Log.i(G.Tag, "volley result: " + jsonResult);
}
};
Response.ErrorListener errorListener= new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.d(G.Tag, "Error: " + error
+ "\nStatus Code " + error.networkResponse.statusCode
+ "\nCause " + error.getCause()
+ "\nnetworkResponse " + error.networkResponse.data.toString()
+ "\nmessage" + error.getMessage());
}
};
StringRequest request = new StringRequest (
Request.Method.POST,
url,
listener,
errorListener
)
{
#Override
public Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("username", username);
params.put("password", password);
params.put("grant_type", "password");
return params;
}
} ;
G.getInstance().addToRequestQueue(request);
}
{
"error": "unsupported_grant_type"
}
when i have used your request on postman i am getting the error because the body is incorrect of the volley.
Related
The following Android Volley GET Request is failing with the following error message:
E/Volley: [1038] BasicNetwork.performRequest: Unexpected response code 401 for
This is the Request:
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
final String url = "https://xxxxxxxx/storage/v1/items";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
StringBuilder formattedResult = new StringBuilder();
JSONArray responseJSONArray = response.getJSONArray("items");
for (int i = 0; i < responseJSONArray.length(); i++) {
formattedResult.append("\n" + responseJSONArray.getJSONObject(i).get("no") + "=> \t" + responseJSONArray.getJSONObject(i).get("ean")
+ "=> \t" + responseJSONArray.getJSONObject(i).get("name")
+ "=> \t" + responseJSONArray.getJSONObject(i).get("type")
+ "=> \t" + responseJSONArray.getJSONObject(i).get("destruction")
+ "=> \t" + responseJSONArray.getJSONObject(i).get("archived")
);
}
txtShowTextResult.setText("List of Items \n" + " Number" + "\t EAN \n" +
"\t Name \n" + "\t Type \n" + formattedResult);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
txtShowTextResult.setText("An Error occured while making the request");
}
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
String credentials = "username:password";
String auth = "Basic "
+ Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
headers.put("Content-Type", "application/json");
headers.put("Authorization", auth);
return headers;
}
});
requestQueue.add(jsonObjectRequest);
I am not sure why the Request is failing, as I am new to Android Volley.
Possible cause: the method getHeaders() is not called, but I donĀ“t know where to put the Method call in the Request and therefore, I would appreciate any help, hints or feedback. Thanks in advance!
Adding the missing part at your code you can try out the following. Notice the override part of getHeaders, let me know how it goes.
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//handle response
}
}
, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//handle error
}
}){
#NotNull
#Override
public Map<String, String> getHeaders() {
//Handle headers inside here
Map<String, String> headers = new HashMap<>();
String credentials = "username:password";
String auth = "Basic "
+ Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
headers.put("Content-Type", "application/json");
headers.put("Authorization", auth);
return headers;
}
};
requestQueue.add(jsonObjectRequest);
I'm trying to do an HTTP PUT with JSON to a service that needs HTTP Basic Auth, but I keep getting client errors. I do this:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.PUT, payOp.getURL(), payOp.getJson(), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("jsonObjectRequest", "Response " + response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("jsonObjectRequest", "Error " + error.toString());
Log.i("jsonObjectRequest", "Error ", error);
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
ApplicationSettings applicationSettings = ApplicationSettings.getInstance();
String username = applicationSettings.mMID;
String password = applicationSettings.mAPIPassword;
String creds = String.format("%s:%s",username, password);
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.NO_WRAP);
Log.i("jsonObjectRequest","Authorization is: " + auth);
params.put("Authorization", auth);
return params;
}
};
queue.add(jsonObjectRequest);
And I get back:
2019-05-04 17:52:40.158 7430-7430/com.amex.gatewaydemotr5 I/jsonObjectRequest: Error
com.android.volley.ClientError
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:199)
at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:131)
at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:111)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:90)
I can't figure out what I'm doing wrong. I'm making the creds string correct (I have another app written in node.js that works to compare the output to) but I don't get a lot of output from Volley for an error. Can anyone see what I'm doing wrong? Is there some way to get more detail out of Volley on the error? Thanks!
Ok, figured it out. It was a problem with my URL & Data, but the main thing was I didn't understand how to parse the errors, for anyone who needs to know there's a networkResponse object on the error that has statusCode and data parameters. The server messages are there. The data parameter comes back as a byte array, so you have to wrap it in a string object to see the results.
Once I understood that I could get the messages back I needed and fix the problem, here's the code:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.PUT, payOp.getURL(), payOp.getJson(), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("jsonObjectRequest", "Response " + response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("jsonObjectRequest", "Error, Status Code " + error.networkResponse.statusCode);
Log.i("jsonObjectRequest", "URL: " + payOp.getURL());
Log.i("jsonObjectRequest", "Payload: " + payOp.getJson().toString());
Log.i("jsonObjectRequest", "Net Response to String: " + error.networkResponse.toString());
Log.i("jsonObjectRequest", "Error bytes: " + new String(error.networkResponse.data));
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
ApplicationSettings applicationSettings = ApplicationSettings.getInstance();
String username = applicationSettings.mMID;
String password = applicationSettings.mAPIPassword;
String creds = String.format("%s:%s",username, password);
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.NO_WRAP);
Log.i("jsonObjectRequest","Authorization is: " + auth);
params.put("Authorization", auth);
return params;
}
};
The important part is this:
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("jsonObjectRequest", "Error, Status Code " + error.networkResponse.statusCode);
Log.i("jsonObjectRequest", "URL: " + payOp.getURL());
Log.i("jsonObjectRequest", "Payload: " + payOp.getJson().toString());
Log.i("jsonObjectRequest", "Net Response to String: " + error.networkResponse.toString());
Log.i("jsonObjectRequest", "Error bytes: " + new String(error.networkResponse.data));
}
Having trouble on VolleyRequest getting always error response when loading it onCreate. I want to do is when the fragment loads. but when I try it, the Logcat gives me an error 400. on this Java class, i have another function that has sending data to API. I just copied my code :). here is the code that getting a error response.
String url = "MYLINK.com";
try {
RequestQueue queue = Volley.newRequestQueue(getActivity());
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(getContext(), "Successful send pending data", Toast.LENGTH_SHORT).show();
String qu = ("update tickets set is_send = '1' where ticket_tick_no = '" + ticket_tick_no_delayed + "'");
sqldb.execSQL(qu);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(), "Error Response here", Toast.LENGTH_SHORT).show();
Log.e("------", String.valueOf(error.networkResponse.statusCode));
}
}
) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("control_no", trip_no_delayed);
params.put("trip_no", ticket_control_no_delayed);
params.put("ticket_no", ticket_tick_no_delayed);
params.put("ticket_datetime", ticket_datetime_delayed);
params.put("ticket_kmfrom", ticket_kmfrom_delayed);
params.put("ticket_kmto", ticket_kmto_delayed);
params.put("ticket_placefrom", ticket_placefrom_delayed);
params.put("ticket_placeto", ticket_placeto_delayed);
params.put("amount", ticket_amount_delayed);
params.put("discount", ticket_discount_delayed);
params.put("trans_type", transaction_type_delayed);
params.put("passenger_type", passenger_type_delayed);
params.put("lat", ticket_lat_delayed);
params.put("long", ticket_long_delayed);
params.put("device_serial", device_serial_delayed);
return params;
}
};
queue.add(postRequest);
} catch (Exception e) {
e.printStackTrace();
}
I am trying to connect to a django server from my android application. I am trying to access my api, making a POST request with volly. Everything is set. All the params and headers required, but still I get this error.
log: [490] BasicNetwork.performRequest: Unexpected response code 401 for https://example.com/
It's not letting me access my django Api. It works fine with the PHP server.
public void vollyRequest()
{
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest request = new StringRequest(Request.Method.POST , "https://example.com/", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, "RESPONSE: " + response, Toast.LENGTH_SHORT ).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "ERROR: " + error, Toast.LENGTH_SHORT ).show();
}
}) {
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("username","***");
params.put("password","***");
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");
// return params;
// }
};
queue.add(request);
}
i solved it my self...
This code will get you an auth-token, with the username and password you provide, and then that token will be put in the header to get data from the server...
public void vollyRequestGetAuthToken()
{
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest request = new StringRequest(Request.Method.POST , "https://example.com/get-auth-token/", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, "RESPONSE: " + response, Toast.LENGTH_SHORT ).show();
System.out.println("RESPONSE: >>> " + response + "<<<");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "ERROR: " + error, Toast.LENGTH_SHORT ).show();
}
}) {
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("username","*****");
params.put("password","*****");
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("Authorization",
String.format("Basic %s", Base64.encodeToString(
String.format("%s:%s", "<username>", "<password>").getBytes(), Base64.DEFAULT)));
params.put("username" , "*****" );
params.put("password" , "*****" );
return params;
}
};
queue.add(request);
}
and now when you have the auth-token, use the following code to send auth-token to get data
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", "Token <token>");
return headers;
}
This is caused when the request is declined/blocked from the API End Point.
The reason could be a malformed request for that,
Check your request type [GET/POST/ANY OTHER]
Check the request Header and Body
I'm trying to convert my app to use WebAPI and token authenication. I'm also moving away from Apache http and using volley.
Below i have a class called NetworkManager that handles the volley requests.
In my main Activity there is a login button that calls a method getAuthenicationTokens from the networkManager class. I have used a customeListener to relay the response back to the calling Activity.
CustomListener:
public interface CustomListener<T>
{
public void getResult(T object);
}
.
Activity:
buttonLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NetworkManager.getInstance().getAuthenticationTokens(null, new CustomListener<JSONObject>()
{
#Override
public void getResult(JSONObject result)
{
Log.e(TAG, "Json object length = " + result.length());
}
});
.
Method in NetworkManager:
public void getAuthenticationTokens(Object param1, final CustomListener<JSONObject> listener)
{
//String url = prefixURL + "this/request/suffix";
String url = "https://lw.xxx.co.uk/connect/token";
Map<String, Object> jsonParams = new HashMap<>();
jsonParams.put("scope", "openid email phone profile offline_access roles");
jsonParams.put("resource", "window.location.origin");
jsonParams.put("grant_type", "password");
jsonParams.put("username", "support#xxx.com");
jsonParams.put("password", "tempPxxx");
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, new JSONObject(jsonParams),
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response)
{
Log.d(TAG + ": ", "somePostRequest Response : " + response.toString());
if(null != response.toString())
listener.getResult(response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
if (null != error.networkResponse)
{
Log.d(TAG + ": ", "Error Response code: " + error.networkResponse.statusCode);
listener.getResult(null);
}
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = super.getHeaders();
if(params==null)params = new HashMap<>();
params.put("Content-Type","application/x-www-form-urlencoded");
//..add other headers
return params;
}
};
requestQueue.add(request);
}
.
I have tried to add a header to the request using the following post(answer by Subhash), but i'm getting the following exception from adding the headers.
link
Exception:
NetworkDispatcher.run: Unhandled exception java.lang.UnsupportedOperationException
java.lang.UnsupportedOperationException
at java.util.AbstractMap.put(AbstractMap.java:203)
at loneworker.carefreegroup.com.loneworker.NetworkManager$3.getHeaders(NetworkManager.java:100)
at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:93)
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:112)
.
Has anyone any ideas what what the problem is with adding the headers.
The exception is on line 100, here
params.put("Content-Type","application/x-www-form-urlencoded");
Have you tried:
Map<String, String> params = new HashMap<>(super.getHeaders());
I tested it and it worked for me.