Parse REST response message using retrofit and observable - java

My API returns this when I use wrong login information (using postman):
{
"error": {
"statusCode": 401,
"name": "Error",
"message": "login failed",
"code": "LOGIN_FAILED",
"stack": "Error: login failed\n at ...path..."
}
}
I am using this method to get the response message:
private void handleResponse(retrofit2.Response<Response> response) {
if (response.isSuccessful()) {
emailField.setText(null);
passwordField.setText(null);
Intent intent = new Intent(getActivity(), MainActivity.class);
startActivity(intent);
} else {
try {
showSnackBarMessage(response.errorBody().string());
} catch (Exception e) {
showSnackBarMessage(e.getMessage());
}
}
}
And the output (what snackbar shows) is the same as postman returns.
handleresponse parameter retrofit2.Response<Response> response consists of retrofit2 Response, and my own <Response> class which looks like this:
public class Response {
#SerializedName("message")
#Expose
private String message;
public String getMessage() {
return message;
}
}
How can I get only message to show in snackbar?
I have tried the following code, but I get only No value for message.
try {
JSONObject jObjError = new JSONObject(response.errorBody().string());
Toast.makeText(getContext(), jObjError.getString("message"), Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}

According to your json the response error body is an object with a field error which contains a field message. This means you first need to get the error object and then the message:
JSONObject jObjError = new JSONObject(response.errorBody().string()).getJSONObject("error");
Toast.makeText(getContext(), jObjError.getString("message"), Toast.LENGTH_LONG).show();

Related

Error (JSONException) when i try to upload image from Android to PHP server with Volley

I have an error that I can't fix when I upoload an image from my android device to a PHP web server. More precisely I get the error:
org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONObject
And I honestly can't understand why. I am attaching the PHP script below, in the hope you managed to identify the error.
<?php
// Path to move uploaded files
$target_path = dirname(__FILE__).'.';
if (isset($_FILES['image']['name'])) {
$target_path = $target_path . basename($_FILES['image']['name']);
try {
// Throws exception incase file is not being moved
if (!move_uploaded_file($_FILES['image']['tmp_name'], $target_path)) {
// make error flag true
echo json_encode(array('status'=>'fail', 'message'=>'could not move file'));
}
// File successfully uploaded
echo json_encode(array('status'=>'success', 'message'=>'File Uploaded'));
} catch (Exception $e) {
// Exception occurred. Make error flag true
echo json_encode(array('status'=>'fail', 'message'=>$e->getMessage()));
}
} else {
// File parameter is missing
echo json_encode(array('status'=>'fail', 'message'=>'Not received any file'));
}
?>
While the image upload function is defined in this way
private void imageUpload(final String imagePath) {
SimpleMultiPartRequest smr = new SimpleMultiPartRequest(Request.Method.POST, BASE_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("Response", response);
try {
JSONObject jObj = new JSONObject(response);
String message = jObj.getString("message");
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
}
});
smr.addFile("image", imagePath);
MyApplication.getInstance().addToRequestQueue(smr);
Why do you think I get this error?
Solved.
sudo chmod -R 777 /Users/matteo/.bitnami/stackman/machines/xampp/volumes/root/htdocs

Send json array to add multiple records in mysql to php script using volley in android

I am trying to add multiple records in database i am sending json array using string request method in volley in android to php script to add those records.But haven't getting the result of json array in php. I just want to add multiple records in mysql that why sending json array to script to add those records by fetching all data in it
Here is Insert Data function
private void InsertData() {
if(arrayList.size()>0) {
Toast.makeText(getApplicationContext(), "list not null "+i+arrayList.size(),
Toast.LENGTH_LONG).show();
//for (i=0;i<arrayList.size();i++) {
//Toast.makeText(getApplicationContext(),"inside for loop", Toast.LENGTH_LONG).show();
StringRequest stringRequest = new StringRequest(Request.Method.POST,
Constants.insert_macthes,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getInt("success") == 1) {
Toast.makeText(getApplicationContext(), jsonObject.getString("message"), Toast.LENGTH_LONG).show();
} else
Toast.makeText(getApplicationContext(), "not added", Toast.LENGTH_LONG).show();
dis = jsonObject.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
Toast.makeText(MyMatchas.this,
"Error time out",
Toast.LENGTH_LONG).show();
} else if (error instanceof AuthFailureError) {
//TODO
Toast.makeText(MyMatchas.this,
"Auth Error time out",
Toast.LENGTH_LONG).show();
} else if (error instanceof ServerError) {
//TODO
Toast.makeText(MyMatchas.this,
"Server Error time out",
Toast.LENGTH_LONG).show();
} else if (error instanceof NetworkError) {
//TODO
Toast.makeText(MyMatchas.this,
" Network Error time out",
Toast.LENGTH_LONG).show();
} else if (error instanceof ParseError) {
Toast.makeText(MyMatchas.this,
"Parse Error time out",
Toast.LENGTH_LONG).show();
//TODO
}
}
}) {
#Override
protected Map<String, String> getParams() {
JSONArray array=new JSONArray();
JSONObject jsonObject=new JSONObject();
for(i=0;i<arrayList.size();i++)
{
Log.v("fetching record:",arrayList.get(i).getId());
arr[i]="dog_id"+arrayList.get(i).getId()+"dog_name"+arrayList.get(i).getDog_name()+"score"+arrayList.get(i).getDog_score()+"user_id"+ String.valueOf(SharedPrefManager.getInstance(MyMatchas.this).getUserid());
try {
//Log.v("put in json:",arrayList.get(i).getId());
jsonObject.put("dog_id",arrayList.get(i).getId());
jsonObject.put("dog_name",arrayList.get(i).getDog_name());
jsonObject.put("score",arrayList.get(i).getDog_score());
jsonObject.put("user_id",String.valueOf(SharedPrefManager.getInstance(MyMatchas.this).getUserid()));
} catch (JSONException e) {
Log.v("error exceptiion:",arrayList.get(i).getId());
e.printStackTrace();
}
array.put(jsonObject);
}
HashMap<String ,String> params=new HashMap<String, String>();
Log.v("All data:",jsonObject.toString());
Log.v("json object data:",array.toString());
params.put("params",array.toString());
return params;
}
};
// Creating RequestQueue.
RequestQueue requestQueue = Volley.newRequestQueue(MyMatchas.this);
// Adding the StringRequest object into requestQueue.
requestQueue.add(stringRequest);
// }
// Toast.makeText(getApplicationContext(),dis,Toast.LENGTH_LONG).show();
}
Here is the Php script
<?php
$con=mysqli_connect("localhost","m","rt","Friend");
if($_SERVER['REQUEST_METHOD']=='POST'){
$arr = $_POST['params'];
$json = json_decode($arr,true);
echo $json;
foreach($json as $obj){
$Sql_Query = "INSERT INTO Match_list (dog_id,score,dog_name,User_ID) values
('$obj->dog_id','$obj->dog_name','$obj->score','$obj->user_id')";
if($con->query($Sql_Query) === TRUE)
{
die(json_encode(array("success"=>1,"message"=>"Data Added
Successfuly")));
}
}
}
mysqli_close($con);
?>
You can access values like this:
echo $json[0]["dog_id"];
You need to create new object for every time for holding new values
JSONArray array = new JSONArray();
JSONObject jsonObject;
GettingVaccineData gettingVaccineData;
for (int i = 0; i < vaccineData.size(); i++) {
jsonObject = new JSONObject();
gettingVaccineData = vaccineData.get(i);
try {
jsonObject.put("LCID", reqResponse);
jsonObject.put("LVID", gettingVaccineData.getID());
jsonObject.put("LVNAME", gettingVaccineData.getNAME());
jsonObject.put("LSCHEDULE", scheduleDays.get(i));
jsonObject.put("LGIVEN", "NULL");
jsonObject.put("LSTATUS", "not given");
jsonObject.put("LHOSPITAL", "NULL");
} catch (JSONException e) {
e.printStackTrace();
}
array.put(jsonObject);

Nested volley request with Singleton class returns null

I am getting a error in my code. The outer request returns a data but the inner loop returns null.
What I am doing here is: I am requesting some data and again using the id that I get from the first request, i use it to send another request. Although I am receiving the first response, I am getting ERRORNull message in the second nested request.
I am sure that the url is correct. I have not been able to find the solution to this problem.
private ArrayList<Item> fetchApiData(){
String url="http://www.gadgetsinnepal.com.np/wp-json/wp/v2/posts/";
JsonArrayRequest jsArrayRequest = new JsonArrayRequest
(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
// Parsing json array response
// loop through each json object
for (int i = 0; i < response.length(); i++) {
JSONObject item = (JSONObject) response
.get(i);
String id = item.getString("id");
String date = item.getString("date");
JSONObject titleobj = item
.getJSONObject("title");
String title= titleobj.getString("rendered");
String featuredMedia= item.getString("featured_media");
Toast.makeText(getApplicationContext(), "ID :" + id +" Date: "+ date+ " Title "+ title + featuredMedia,
Toast.LENGTH_SHORT).show();
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
"http://www.gadgetsinnepal.com/wp-json/wp/v2/media/"+featuredMedia, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject nested_response) {
try {
// Parsing json object response
// response will be a json object
JSONObject guilld = nested_response.getJSONObject("guid");
String featured_img_url = guilld.getString("rendered");
String nestid=nested_response.getString("id");
Toast.makeText(getApplicationContext(),nested_response.toString()+"IMAGE" + nestid,Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
"ERROR"+error.getMessage(), Toast.LENGTH_LONG).show();
}
});
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjReq);
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
MySingleton.getInstance(this).addToRequestQueue(jsArrayRequest);
}
This problem was solved by carefully examining where the error log was giving.
Having unique logs in your methods will make finding the place where the problem occurs easier to find.
In this case we found that something was happening in:
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
"ERROR"+error.getMessage(), Toast.LENGTH_LONG).show();
}
Further investigation showed we got a response code 503 message there.
Reasons for this to happen: lifewire.com/503-service-unavailable-explained-2622940
Increasing the time out of the request seems to prevent this from occurring again.

Parsing Json specific field from Response in Android

{
"status":"ok",
"cookie":"dr.steve|akscjn",
"cookie_name":"wordpress_logged_in",
"user": {
"id":330,
"username":"dr.steve",
"nicename":"steve",
"email":"steve#docdirect.com",
"url":"http:\/\/www.company.com",
"registered":"2016-12-15 22:21:05",
"displayname":"Dr.Steve",
"firstname":"Dr",
"lastname":"Steve",
"nickname":"steve",
"description":"Lorem ipsum",
"capabilities":"",
"avatar":null
}
}
I have this json response and i want the only id field from this json , I think there are two nested arrays but i am geting error
E/Error: Json parsing error: Value {"id":330,.........}at user of type org.json.JSONObject cannot be converted to JSONArray
this my code
if (jsonStr != null) {
try {
JSONArray ja = new JSONObject(jsonStr).getJSONArray("user");
JSONObject c = ja.getJSONObject(1);
String id = c.getString("id");
temp2 = id;
Log.v("id---->",temp2);
}
} catch (final JSONException e) {
Log.e("Error", "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e("Error", "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
can anyone tell where i am making a mistake how would i get id field from this json ?
The user property is a concrete object not an array so try to read it as an object:
JSONObject user = new JSONObject(jsonStr).getJSONObject("user");
"user":{ is an object.
Arrays have square brackets. You have no arrays in your data

Android: IllegalStateException thrown

In the LoginActivity.java class, when a user clicks a register button, then the code sets the login session true and then switches the activity from LoginActivity to MainActivity. Here's the login code snippet.
case(R.id.login):
String email = etEmail.getText().toString();
String password = etPassword.getText().toString();
if(email.trim().length() > 0 && password.trim().length() > 0) {
loginManager.checkLogin(email, password);
pDialog.setMessage("Logging in..");
showDialog();
session.setLogin(true);
if(loginManager.isLoginSuccessful()) {
hideDialog();
Toast.makeText(this, getResources().getString(R.string.welcome_msg), Toast.LENGTH_LONG).show();
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
finish();
} else {
Toast.makeText(this, loginManager.getErrorMessage(), Toast.LENGTH_LONG).show();
}
} else if(email.trim().length() < 1) {
Toast.makeText(this, "Please enter the email", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Please enter the password", Toast.LENGTH_SHORT).show();
}
break;
And here's the LoginManager.java file that deals with the login process. I used OkHttp for the HTTP library.
public class LoginManager {
private final String TAG_LOGIN = LoginManager.class.getSimpleName();
private OkHttpClient client = new OkHttpClient();
private final String loginURL = URL.getInstance().getUrlLogin();
private Request request = new Request.Builder().url(loginURL).build();
private static JSONObject jsonObject;
private boolean error;
public void checkLogin(final String email, final String password) {
client.newCall(request).enqueue(new Callback() {
// onFailure is called when the request could not be executed due to cancellation, a connectivity problem or timeout.
#Override
public void onFailure(Request request, IOException e) {
}
// onResponse is called when the HTTP response was successfully returned by the remote server.
// using POST request for login
#Override
public void onResponse(Response response) throws IOException {
Log.d(TAG_LOGIN, "Login response: " + response.body().string());
RequestBody body = new FormEncodingBuilder()
.add("tag", "login")
.add("email", email)
.add("password", password)
.build();
Request request = new Request.Builder().url(loginURL).post(body).build();
client.newCall(request).execute();
try {
jsonObject = new JSONObject(response.body().string());
error = jsonObject.getBoolean("error");
} catch(JSONException e) {
e.printStackTrace();
}
}
});
}
public boolean isLoginSuccessful() {
if(error) {
return false;
}
return true;
}
public String getErrorMessage() {
String errorMessage = null;
try {
jsonObject.getString("error_msg");
} catch(JSONException e) {
e.printStackTrace();
}
return errorMessage;
}
}
When I run the application, it shows the welcome toast message and suddenly quits with the following error log.
java.lang.IllegalStateException: closed
at com.squareup.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:454)
at okio.Buffer.writeAll(Buffer.java:574)
at okio.RealBufferedSource.readByteArray(RealBufferedSource.java:87)
at com.squareup.okhttp.ResponseBody.bytes(ResponseBody.java:56)
at com.squareup.okhttp.ResponseBody.string(ResponseBody.java:82)
at com.marshall.thequizshow.application.http.LoginManager$1.onResponse(LoginManager.java:51)
at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:150)
at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
So, I must be having a bug with the try-catch phrase under the onResponse method in the LoginManager.java file.
try {
jsonObject = new JSONObject(response.body().string());
error = jsonObject.getBoolean("error");
} catch(JSONException e) {
e.printStackTrace();
}
I would like to ask you how I should fix the code so that it no longer catches the IllegalStateException.
Thank you in advance.
As a general answer, YES: The proper way to avoid a RuntimeException is to fix the code: They should not be catched by program, under normal circunstances.
Now, let's see your case... The IllegalStateException arises because the HttpConnection seems to be closed when trying to use it. Could it be because you are calling twice the method response.body()?
IllegalState exception is thrown when you call a method at a wrong time. Check the nature of your process then restructure you code to make the call at an appropriate time

Categories

Resources