Volley JsonObjectRequest doesn't accept JsonObject as response - java

I've been stock for a while and seems like Google volley isn't working as I expect.
I've a JsonObject request prepared as this:
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("auth-code", authCode);
} catch (JSONException ignored) {
}
JsonObjectRequest response = new JsonObjectRequest(UrlController.getGoogleOauthSendAuthCodeMethod(), UrlController.getGoogleOauthSendAuthCodeUrl(), jsonObject.toString(), onSuccess, onError);
AppController.getInstance().addToRequestQueue(response, "REGISTER_USER_GOOGLE_OAUTH");
It just sends google auth-code to my server and gets a jsonObject as response.
In response to that request I retrieve this:
{"data":{"user":
{"name":"name lastname",
"username":"someusername",
"email":"email#gmail.com"},
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjQxNDIsImlzcyI6Imh0dHA6XC9cL2FzaG9qYXNoLm1pbFwvYXBpXC92MVwvYXV0aFwvZ29vZ2xlIiwiaWF0IjoxNDUyNDY3NTQ4LCJleHAiOjE0NTI0NzExNDgsIm5iZiI6MTQ1MjQ2NzU0OCwianRpIjoiMTNhNjU0MjcwMmQ2MmE5MDA1YTgyZTlkZTM3YjQxNGQifQ.YfQaGuhVTYXPizdt2AX8C0RAObUNoqJp4rglZPOGW7s",
"is_new_user":false
}
}
But Volley always, enters onError section.
I have tested the server api, as it returns this data.
Some note-worthy thing:
When I return this json object, without checking the auth-code and just returning a random user from the database, the code enters the onResponse callback. I've logged the server, I got auth-code there too ,and retrieving response correctly.
So what I'm doing wrong?

Found the reason, Volley time-out request is 2.5 sec.
I was authenticating an auth-code which was taking more than that time.
To solve it use this code snippet for your Volley Request
response.setRetryPolicy(new DefaultRetryPolicy(15000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
15000 is requestTimeOut in ms.

Related

send json to Laravel using postman and android

i am trying to send json using postman to Lavavel but i facing this error.
enter image description here
this is my json code:
{
"email":"test#test.com",
"password":"testtest"
}
and this is Laravel codes :
Route::get('/r','test#store');
and
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use Log;
class test extends Controller
{
public function store(Request $request)
{
$email = $request->input('email');
$password = $request->input('password');
Log::info('test');
Log::info($email);
Log::info($password);
DB::table('login')->insert([
['email' => $email],
['password' => $password]
]);
}
}
also i trying using android for send data using volley and so checked Laravel logs :
Column 'email' cannot be null (this is Laravel logs)
and on android Logs:
E/Volley: [299] BasicNetwork.performRequest: Unexpected response code 500 for http://192.168.1.4:8000/r
D/error: com.android.volley.ServerErro
my android code is :
public class ApiService {
private final Context context;
public ApiService(Context context){
this.context=context;
}
public void loginUser(String email, String password, final OnLoginResponse onLoginResponse){
JSONObject requestJsonObject=new JSONObject();
try {
requestJsonObject.put("email",email);
requestJsonObject.put("password",password);
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, "http://192.168.1.4:8000/r",requestJsonObject , new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("response",response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("error",error.toString());
}
}) {
#Override
public Map getHeaders() throws AuthFailureError {
HashMap headers = new HashMap();
headers.put("Content-Type", "application/json");
return headers;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(18000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(context).add(request);
} catch (JSONException e) {
Log.e(TAG, "loginUser: "+e.toString());
}
}
public interface OnLoginResponse{
void onResponse(boolean success);
}
}
I hope this helps people trying to search on how to send JSON data to laravel not only specific to android applications but to all. The goal of this solution is to identify whether you can send a JSON data to laravel or not.
First of all you have to download postman from https://www.getpostman.com/ to test if your API is really working or not.
Create a post request using postman. Be sure that you follow the example data below
Be sure that you set your Routes that would associate to the controller
This is the controller part that will show the JSON data you sent if it was successfully accepted or not.
And also, if ever you are trying to send POST data to laravel, by default they provided a CSRF Token which is applicable for the forms if you are going to use the MVC of laravel. For the meantime, we are going to take this down and comment it out. Just go to app/http/kernel.php
and now you'll get the following result from the code earlier
$json = json_decode($request['json']);
echo $json->{'email'};
echo "\n";
echo $json->{'password'};
We tested that we were able to send data to laravel. I hope this truly helps.
Wen you want to send data, you will want to use POST or PUT method on your postman, specially if you are sending a body, that means that you are sending data. Get method is used to retrieve data from a service.
Take a look into CRUD functions for more information.
Your postman should look something like this
Last in your android code try to change this line
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, "http://192.168.1.4:8000/r",requestJsonObject , new Response.Listener<JSONObject>() {
to use Request.Method.POST

Exception Handling In Android from Web API

My code in MVC API C# this:
[System.Web.Http.HttpPost]
[System.Web.Http.Route("api/ServiceV1/Test")]
public IHttpActionResult Test()
{
return BadRequest("Catch this message in Android application");
}
Result in PostMan
{
"Message": "Catch this message in Android application"
}
I catch this error message on android application. I used okhttp3.
String MIME_JSON = "application/json";
Gson gson = new Gson();
RequestBody body = RequestBody.create(MediaType.parse(MIME_JSON), gson.toJson(object));
Request request = new Request.Builder()
.url(baseUrl + route)
.post(body)
.build();
okHttpClient.newCall(request).execute();
How do to catch this message on the Android application?
the Call.execute() method returns a Response object, which has the code() method to find the status code, and the isSuccessful() method to find whether the code is in the [200,300) range, which generally represent success.
Generally looking at the documentation of libraries you are working with is helpful. Here's the documentation for okhttp
Can read this error:
Response response=okHttpClient.newCall(request).execute();
if (response.code() != 200) {
errorMessage= response.body().string();
}

Reddit Api GET request succeeds in Postman, but fails with Retrofit

I am attempting to get a user's Reddit front page. I have successfully received an Auth Token via the Token Retrieval (code flow). I have managed to get the expected JSON response via Postman, but cannot produce the same results with Retrofit. The request seems to be timing out as onFailure() is being triggered in the callback. I am using the scopes: identity, mysubreddits, and read.
Additional note: I have got a 401 and 403 response with the code below when using insufficient scopes and using an expired Auth Token respectively.
Relevant constants:
redditToken = (actual auth token String)
RedditConstants.REDDIT_BASE_URL_OAUTH2 = "https://oauth.reddit.com"
Relevant method Section:
if (redditToken != null) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RedditConstants.REDDIT_BASE_URL_OAUTH2)
.addConverterFactory(GsonConverterFactory.create())
.build();
Api api = retrofit.create(Api.class);
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "bearer " + redditToken);
headers.put("User-Agent", RedditConstants.REDDIT_USER_AGENT);
Call<RedditFeed> call = api.getFeed(headers);
call.enqueue(new Callback<RedditFeed>() {
#Override
public void onResponse(Call<RedditFeed> call, Response<RedditFeed> response) {
Log.d("FINDME", "response "+ response.toString());
if (response.isSuccessful()) {
Log.d("FINDME", "response was a success! we got the feed!");
} else {
Log.d("FINDME", "responce was not successfull triggered");
}
}
#Override
public void onFailure(Call<RedditFeed> call, Throwable t) {
Log.d("FINDME", "onFailure called from populateRedditFeed");
}
});
} else {
Toast.makeText(this, "Please Login with Reddit", Toast.LENGTH_SHORT).show();
}
Retrofit Interface:
public interface Api {
#GET(".")
Call<RedditFeed> getFeed (
#HeaderMap Map<String, String> headers
);
}
Log Results:
D/NetworkSecurityConfig: No Network Security Config specified, using
platform default
I/zygote: Do full code cache collection, code=123KB, data=105KB
After code cache collection, code=111KB, data=79KB
D/FINDME: onFailure called from populateRedditFeed
Postman Success:
After many starts and stops, seemingly randomly getting either a 200 or calling onFailure() I discovered the problem in one of my Retrofit model classes. The JSON response from Reddit contains a field that can either be a long or boolean. I had it defined as a boolean in my java class which threw an llegalStateException when it was returned as a long.
type name description
special edited false if not edited, edit date in UTC epoch-seconds
otherwise. NOTE: for some old edited comments on reddit.com, this will
be set to true instead of edit date.
*I'm unsure how to deal with this duality of types in java so for now I've commented out the field and the code works as expected.

302 Response for session management from ajax request

I am trying to manage a user session by making an ajax request to java code repeatedly
function sendSessionKeepAliveRequest() {
$.get('${URL}/sessionKeepAlive?nd=' + new Date().getTime());
}
and java code (spring framework used) handling this request:
#RequestMapping("/sessionKeepAlive")
public String dummySessionKeepAlive(HttpServletResponse response,
HttpServletRequest request) {
PrintWriter writer = null;
try {
writer = response.getWriter();
} catch (IOException e) {
logger.error(e.getMessage());
}
if (writer != null) {
response.setContentType("application/json");
// Sending an empty JSON response.
Gson gson = new Gson();
writer.write(gson.toJson(""));
}
return null;
}
Now the issue is some times were are getting 302 Found instead of 200 OK which makes jsessionid change and session got time out.I have tested in on IE and FF and both of the browser have same behaviour.
Code is deployed on IBM websphere v7.0
Please help or any direction.Please feel free if any more inputs are required or I need to modify my question.
Kind Regards
You have encountered a so-called redirection: The url of the resource you've requested has changed. The new url is provided in the http header 'Location'.
You can either read out this location and issue another Request using this url or you can set up your response handling code to automatically follow the redirection.
Sample code:
function sendSessionKeepAliveRequest() {
$.ajax(
url: '${URL}/sessionKeepAlive?nd=' + new Date().getTime()
, statusCode: {
302: function ( jqXHR, textStatus, errorThrown ) {
var url_trg = jqXHR.getResponseHeader('Location');
$.get(url_trg);
}
}
});
Update
jquery ajax requests should handle 302 status codes automatically, so there might be some other problem. Could it possibly be a cross-domain issue ?
If the purpose is just only to alive session then no need to use GSON you can pass empty String and add one annotation
#ResposeBody
This will help you to get ajax response.

Using the LinkedIn invitation with Scribe and Android

Hi I'm using Scribe to Send a LinkedIn invite, but I'm a little unsure how to use it. I've created the XML body as a string with all the neccessary values inserted but when I make the API call the invite isn't sent. My code is as follows
invite.setOnClickListener(new Button.OnClickListener()
{
public void onClick (View v)
{
inviteXml = inviteCreator.inviteString(to, subj, body, authName, authValue);
titleField.setText("");
call = "http://api.linkedin.com/v1/people/~/mailbox";
request = new OAuthRequest(Verb.POST, call);
//request.addPayload(inviteXml);
request.addBodyParameter("body", inviteXml);
service.signRequest(accessToken, request);
response = request.send();
nameField.setText(response.getBody());
invite.setVisibility(View.GONE);
}
});
on the line request.addPayload(inviteXml); this causes the app to crash. The line request.addBodyParameter("body", inviteXml); returns an error xml message that has a status of 400 with an error code 0 and tht message "Couldn't parse mailbox-item document: error:Unexpected end of file after null"
Am I going about this the wrong way or have I missed something inportant? I've read the LinkedIn documentation but it doesn't seem to say how to add the xml message to the appi call.
Thanks for any help
Jeff
Have you tried to specify Content-Lenght and Content-Type ?
Something like this:
request.addHeader("Content-Length", Integer.toString(inviteXml.length())); request.addHeader("Content-Type", "text/xml");
request.addPayload(inviteXml);

Categories