Internal server error while connecting to Server in android using volley? - java

here my function code to post using volley
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_CHECK_IN,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
int status = jsonObject.getInt("status");
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError response) {
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
public Map<String, String> getHeaders () {
Map<String, String> map = new HashMap<String, String>();
map.put("Content-Type", "application/json");
map.put("appid", appids);
map.put("timestamp", timestamps);
map.put("token", tokens);
map.put("signature", signatures);
return map;
}
};
}
I don't know what's wrong with my code, because of 2 days ago everything fine.
and when I tried to debug, error show like this
BasicNetwork.performRequest: Unexpected response code 500 for http://api/presence/check_in
can anyone help me, please? because I'm stuck and need help or reference to solve my error
thank you

HTTP code 500 is Internal Server Error. Read more here. It generally implies that server is not able to process the request and come up with a response. This means that the code for your application might be alright whereas the server might be encountering some issue processing the current request body. I see that you are sending String in your request body. One peculiar thing I noticed with sending String in request body is that, we also need to check if the String is null or not, better to to use .trim() method at the end of your string too, which will delete starting and trailing spaces. Something simple like not escaping single quotes ( ' ) for the field you are trying to insert onto the database at your server might cause this. So server side field validation and best practices like Prepared Statements is also crucial. If you are absolutely sure that your client end [android app] is alright, maybe the server is encountering some issue at the endpoint you are hitting.
Test your api with a rest client like POSTMAN or INSOMNIA to be absolutely sure that your server and api layer is working as intended. Good Luck

Related

Android: Volley request is not working in released APK while works in debug

I have created a simple volley request for POST
//post request handler
public void PostRequest(final int queryType, String url, final String jsonData) {
StringRequest req = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
for (ApiRequestHandler commHandler : responseListeners) {
commHandler.responseHandler(response);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
for (ApiRequestHandler commHandler : errorListeners) {
commHandler.errorHandler(error);
}
}
}) {
#Override
public byte[] getBody() {
return jsonData.getBytes();
}
#Override
public String getBodyContentType() {
return "application/json";
}
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json; charset=utf-8");
return headers;
}
};
getVolleyQueue().add(req);
}
This method works when I send request in debug mode (Android device connected to Android Studio), while it does not work when I release the app and I get a 400 error.
I have added Internet permissions.
It is difficult to debug when app is released, I just tried to toast when the error is received. The stacktrace is like that, but of no help to me.
com.android.volley.toolbox.BasicNetwork.a(Unknown Source:255),
com.android.volley.NetworkDispatcher.b(Unknown Source:37),
com.android.volley.NetworkDispatcher.run(Unknown Source:5)
I have spent like a day solving this, few of my pointers:
I could see body being blank when request sent from release on server side, but prints data at APK level
I also tried jsonData.getBytes("utf-8"); but didn't work
I am using implementation 'com.android.volley:volley:1.1.1'
I also need some guidelines on better ways to debug released apks. Thank you!
After little more digging, I could find the root cause:
The issue was because I have ProGuard enabled for release build type as minifyEnabled true. It compresses and obfuscates the code by various means like changing class names, variables, constants, etc.
Gson, uses dynamic key naming to make keys short.
To solve this, I used #SerializedName("keyName") annotation to let Gson know what to consider as the key.
For ex:
public class UserInfo {
#SerializedName("user_name")
public String userName;
#SerializedName("mobile")
public String mobile;
}
Hope this saves someone's day!

WearOS cannot make Volley request to an endpoint running on my computer's localhost

Problem
I'm attempting to make a simple POST JsonObjectRequest from a Huawei Watch and I keep getting com.android.volley.TimeoutError. I can successfully make other POST JsonObjectRequests from the watch to a different endpoint (not on my computer's localhost) and I can successfully make requests to the desired endpoint from a laptop.
What I've Tried:
Most posts suggest that this error is due to a bad connection or an incorrect endpoint. I tried increasing the timeout period to see if my connection was just slow but this did not fix things. The endpoint is definitely correct as it works when I make the request from a laptop.
I read on several posts that there are issues when connecting to unknown certificates. I followed the quick fix outline here: https://newfivefour.com/android-trust-all-ssl-certificates.html but this made no difference
My Code
mRequestQueue.add(volleyRequest());
...
private JsonObjectRequest volleyRequest(){
JSONObject data = null;
try{
data = new JSONObject("{'some':'data','other':'data'}");
} catch (JSONException e){
e.printStackTrace();
}
JsonObjectRequest request = new JsonObjectRequest(POST, mPath, data,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("Volley Response", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("Volley Error", error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
headers.put("Authorization", mToken);
return headers;
}
};
return request;
}

How to receive confirmation in Volley or Retrofit?

I want to post some data to a MySQL database. The server-side code will determine whether the data is valid and respond with that determination. Upon receiving this response, the application-side code must decide if it needs to try again or continue on. I have tried callbacks, RequestFuture, and spin-waiting, but it is starting to seem like this type of functionality is not possible with Volley (making decisions based on the server response). Has anyone else had success in implementing this type of functionality?
Main Thread
postCampaign(campaign);
if (//data was invalid) {
//do postCampaign(campaign) again
}
Main Thread
private void postCampaign(final Campaign campaign) {
campaign.setRoomCode("XXXXXXXX");
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// I want to make a decision based on response
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
...
}
}
) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
// put data
return params;
}
};
NetworkController.getInstance(this).addToRequestQueue(request);
}
from server side, you need to grab the data send by your app. Then you need to check for validations like is the passed data empty/incorrect(incase of passwords check for it against the password in database if its the correct one or not).
In the server side validation of your data, if the data is successfully validated and updated in database then give a success response with proper response code or else if database updation is failed, then give an error response with proper error response code. You may pass these response as a json format to the client(or in whatever format you are comfortable parsing)
Now in the app side you may have a response callback method(available in retrofit/volley). From the response obtained in this callback check if it is a success response or failure response and make appropriate decisions for success/ failure cases

Can't POST JSON using Volley

I've searched a lot but can't find out what's happening. I wrote many variations of this code and here is the most recent one.
Android code
private static void post(#NonNull String url,
#NonNull Context context,
#NonNull final JSONObject jsonRequest,
#NonNull final ServerConnectionAdapter serverConnectionAdapter){
Log.d(TAG, "post: URL = " + url);
RequestQueue queue = Volley.newRequestQueue(context);
JsonObjectRequest postRequest = new JsonObjectRequest(
Request.Method.POST,
url,
jsonRequest,
serverConnectionAdapter,
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
serverConnectionAdapter.onErrorResponse(null, error);
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<>();
// map.put("user", json.toString());
map.put("user", "{\"id\":-1,\"name\":\"Gustavo Araujo\"}");
return map;
}
};
queue.add(postRequest);
}
Server (Java) code
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("doPost");
System.out.println("REQUEST: ");
for (Map.Entry<String, String[]> e : request.getParameterMap().entrySet()){
System.out.print(" ");
System.out.println(e.getKey() + ": " + java.util.Arrays.toString(e.getValue()));
}
System.out.println("end");
}
doPost method output
doPost
REQUEST:
end
I've been starring my screen for so long that I think I can't find where is the error. I did find many examples, with and without the getParams(). I tried both, and didn't change anything.
The ServerConnectionAdapter is an abstract class that I created to unify the response with the error listener. I am sure that it is not the problem because it does work flawlessly with the GETs that I have.
The String url also can't be wrong (otherwise the server wouldn't have been triggered.
The jsonRequest also isn't the problem because I already used null there and didn't change the results at all.
As I said, I've been starring this code for hours, all my assumptions may be completely wrong, that's why I'm asking for help.
The error photo you posted in comment in telling me that your request was successful, there isn't any issue from mobile side. The issue is from server side. Because when you are making the request it's going on server but your server is not returning any proper Json. It's returning nothing that's why you are getting that exception. Android request needs a Json in return but you are server is not returning that.
There is a possibility that the issue can be from app side and the cause for that is that maybe you are not sending the proper parameters to server. But as far as I can see, the main issue is from server side. Because all these exceptions are not handled on server side. Like when the parameters are wrong it should return a json with message telling you that the parameters are wrong.
I was doing it wrong. The way that I wrote the doPost method I was reaching the request parametes, like when you access http://localhost:8080/something?key=value what is not what I intend to do.
I needed to read the body of the request. To do so, in Java, it should be as the code below:
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Get the body of the request
BufferedReader reader = request.getReader();
// Print each line
String line;
while ((line = reader.readLine()) != null){
System.out.println(line);
}
}
Thank you for Zohaib Hassan for trying to help.

GET request using GWT to retrieve XML data?

Oh hello there, fellow SO members,
I have a web service that returns XML data using a simple get request that goes like this :
http://my-service:8082/qc/getData?paramX=0169&paramY=2
the service returns raw xml in the page according to the parameters' values.
I am trying to retrieve this data from a GET request in GWT using RequestBuilder, Request, etc.
However, the response gives me empty text, a Status code of ZERO (which doesn't mean anything and isn't supposed to happen), and so on.
Here's the simplified code that doesn't work.
public class SimpleXML implements EntryPoint {
public void onModuleLoad() {
this.doGet("http://my-service:8082/qc/getData", "0169", "2");
}
public void doGet(String serviceURL, String paramX, String paramY) {
final String getUrl = serviceURL + "?paramX=" + paramX + "&idTarification=" + paramY;
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, getUrl);
try {
Request response = builder.sendRequest(null, new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
response.getStatusCode(); // Gives me 0 (zero) :(
}
#Override
public void onError(Request request, Throwable exception) {
// ... doesn't matter for this example
}
});
} catch (RequestException e) {
// ... doesn't matter for this example
}
}
}
I don't get why this wouldn't work, since this is REALLY simple, I've seen tutorials and they all show me this way of doing things..
Thanks in advance
The reason is, that browsers do not allow cross-site requests with AJAX (see Same Origin Policy).
This means, that you can only call a service on the same server, same port (using the same protocol) as your HTML page. If you want to perform cross-site requests, you can use JSONP, as explained in http://code.google.com/webtoolkit/doc/latest/tutorial/Xsite.html.

Categories

Resources