Android AsyncTask, handle unavailable server - java

I am using this tutorial:
http://hmkcode.com/android-parsing-json-data/ to get JSON data from server on virtual machine. It works fine, when server is turned on, but my app crashes when server is unavailable.
How should I handle this situation?
After pressing button I execute:
httpAsyncTask.execute("http://localhost:3000"); //changed on purpose, it works with given IP
httpAsyncTask class:
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
return GET(urls[0]);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
Toast.makeText(getBaseContext(), "Worked fine", Toast.LENGTH_LONG).show();
goToMyActivity();
}
}
In debug my app stops at:
HttpResponse httpResponse = httpclient.execute(new HttpGet(url));
int GET method:
public static String GET(String url){
InputStream inputStream = null;
String result = "";
try {
// create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// make GET request to the given URL
HttpResponse httpResponse = httpclient.execute(new HttpGet(url));
// receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
// convert inputstream to string
if (inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e){
Log.e("Http:",e.toString());
}
return result;
}
Caught exception was null.

use getResponseCode(); of HttpURLConnection class to make sure that the connection is established successfully.
getResponseCode(); would return 200 if the connection is successful.
int responseCode = -1;
feedURL = "your URL"
HttpURLConnection connection;
connection = (HttpURLConnection) feedURL.openConnection();
connection.connect();
responseCode = connection.getResponseCode();
then use if block to check if 200 is returned by connection.getResponseCode().
the constant HttpURLConnection.HTTP_OK can be used instead of hard coding 200.
if (responseCode == HttpURLConnection.HTTP_OK) {
// do your stuff here
}
else {
// Show some error dialog or Toast message
}

Use the catch block to catch the timeout exception (and others):
String message = "";
try {
//HTTP stuff here
if (responseCode == HttpURLConnection.HTTP_OK) {
// do your stuff here
} else {
// Show some error dialog or Toast message
}
} catch (Exception e) {
message = e.getLocalizedMessage();
e.printStackTrace();
}
// Toast message

This function will return null if it gets timeout otherwise will send the response
public static String Get(String url) {
// Create a new HttpClient
HttpParams params = new BasicHttpParams();
// set your timeouts here
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 10000);
HttpClient httpclient = new DefaultHttpClient(params);
try {
// Execute HTTP GET Request
HttpResponse response = httpclient.execute(new HttpGet(url));
return EntityUtils.toString(response.getEntity());
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

Related

Android HttpsURLConnection - simple POST request with parameters

I've been trying to get a simple android client server app working, and I've had nothing but trouble. I'm hoping someone can look at this code and see what I'm doing wrong, maybe I'm doing things in the wrong order, or forgetting something? Just adding the relevant parts
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.addRequestProperty("Content-Type", "application/json");
// set some made up parameters
String str = "{'login':'superman#super.com','password':'password'}";
byte[] outputInBytes = str.getBytes("UTF-8");
OutputStream os = conn.getOutputStream();
os.write( outputInBytes );
os.close();
// connection.setDoOutput(true); //should trigger POST - move above -> crash
conn.setRequestMethod("POST"); // explicitly set POST -move above so we can set params -> crash
conn.setDoInput(true);
The error I get is
'exception: java.net.ProtocolException: method does not support a
request body: GET'
If I just do a POST request without parameters it's fine, so I guess I should move the connection.setDoOutput(true); or conn.setRequestMethod("POST"); higher up, that should work right? When I do that I get the error:
exception: java.net.ProtocolException: Connection already established.
So, if I try to set to POST before adding parameters it doesn't work, if I try to do it after it doesn't work... what am I missing? Is there another way I should be doing this? Am I adding parameters incorrectly? I've been searching for a simple android networking example, and I can't find any, is there any example the official Android site? All I want to do is a very basic network operation, this is so frustrating!
EDIT: I need to use HttpsURLConnection for reasons not included in the above code- I need to authenticate, trust hosts, etc- so I'm really looking for a potential fix for the above code if possible.
Here is an example of how to post with a JSON Object:
JSONObject payload=new JSONObject();
try {
payload.put("password", params[1]);
payload.put("userName", params[0]);
} catch (JSONException e) {
e.printStackTrace();
}
String responseString="";
try
{
HttpPost httpPost = new HttpPost("www.theUrlYouQWant.com");
httpPost.setEntity(new StringEntity(payload.toString()));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpResponse response = new DefaultHttpClient().execute(httpPost);
responseString = EntityUtils.toString(response.getEntity());
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
And example of how to get
String responseString = "";
//check if the username exists
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("www.theUrlYouQWant.com");
ArrayList<String> existingUserName = new ArrayList<String>();
try
{
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
}
else
{
Log.e(ParseException.class.toString(), "Failed to download file");
}
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
I followed this tutorial on making http calls:
http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
Works fine with no problems.
Below is a class that I have modified from the sample:
public class ServiceHandler {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
String TAG = ((Object) this).getClass().getSimpleName();
public ServiceHandler() {
}
/**
* Making service call
*
* #url - url to make request
* #method - http request method
*/
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/**
* Making service call
*
* #url - url to make request
* #method - http request method
* #params - http request params
*/
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 2000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 2000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
Log.e("Request: ", "> " + url);
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
if (httpResponse != null) {
httpEntity = httpResponse.getEntity();
} else {
Log.e(TAG, "httpResponse is null");
}
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
And this is how I use the class:
nameValuePairs = new ArrayList<NameValuePair>();
String param_value = "value";
String param_name = "name";
nameValuePairs.add(new BasicNameValuePair(param_name, param_value));
// Creating service handler class instance
sh = new ServiceHandler();
String json = sh.makeServiceCall(Utils.getUrl, ServiceHandler.GET, nameValuePairs);

Perform AsyncTask on Android / Posting JSON

I am working on an android app, and am running into some troubles with registering users. I want to post a JSON object to my server and receive one back. I can successfully create a JSON object with the right information but when I go to post it I get a NetworkOnMainThreadException or my HttpClient class returns null when it should be returning a JSONObject and I am very confident that my web server works correctly. I understand that you cannot connect to the network on the main thread and have created an HttpClient class that uses AsnycTask (although probably not correctly). I have been working on this for quite a while and would appreciate any guidance in the right direction.
//Main activity
#Override
public void onClick(View arg0) {
if(!(isEmpty(name) || isEmpty(username) || isEmpty(password) || isEmpty(email))) {
user = new JSONObject();
try {
user.put("username", username.getText().toString());
user.put("name", name.getText().toString());
user.put("email", email.getText().toString());
user.put("password", password.getText().toString());
} catch (JSONException e) {
e.printStackTrace();
}
jRegister = new JSONObject();
try {
jRegister.put("apiToken", Utilities.apiToken);
jRegister.put("user", user);
Log.i("MainActivity", jRegister.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
//
HttpClient client = new HttpClient(url, jRegister);
result = client.getJSONFromUrl();
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}else {
tv.setText("");
}
}
HttpClient Class
public class HttpClient extends AsyncTask<Void, Void, JSONObject>{
private final String TAG = "HttpClient";
private String URL;
private JSONObject jsonObjSend;
private JSONObject result = null;
public HttpClient(String URL, JSONObject jsonObjSend) {
this.URL = URL;
this.jsonObjSend = jsonObjSend;
}
public JSONObject getJSONFromUrl() {
this.execute();
return result;
}
#Override
protected JSONObject doInBackground(Void... params) {
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(URL);
StringEntity se;
se = new StringEntity(jsonObjSend.toString());
// Set HTTP parameters
httpPostRequest.setEntity(se);
httpPostRequest.setHeader("Accept", "application/json");
httpPostRequest.setHeader("Content-type", "application/json");
long t = System.currentTimeMillis();
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-t) + "ms]");
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream instream = entity.getContent();
// convert content stream to a String
String resultString= convertStreamToString(instream);
instream.close();
resultString = resultString.substring(1,resultString.length()-1); // remove wrapping "[" and "]"
JSONObject jsonObjRecv = new JSONObject(resultString);
// Raw DEBUG output of our received JSON object:
Log.i(TAG,"<JSONObject>\n"+jsonObjRecv.toString()+"\n</JSONObject>");
return jsonObjRecv;
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(JSONObject jObject) {
result = jObject;
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
I understand that you cannot connect to the network on the main thread
and have created an HttpClient class that uses AsnycTask (although
probably not correctly).
You are right you have not implemented it the right way.
In your onClick events (still on Main thread) you performed a network activity causing the error:
HttpClient client = new HttpClient(url, jRegister);
result = client.getJSONFromUrl();
Instead you should run the network operation inside of the AsnycTask
public class GetJsonTask extends AsyncTask<Void, Void, JSONObject >{
private String URL;
private JSONObject jsonObjSend;
public GetJsonTask(String URL, JSONObject jsonObjSend) {
this.URL = URL;
this.jsonObjSend = jsonObjSend;
}
#Override
protected JSONObject doInBackground(Void... params) {
JSONObject jsonObjRecv;
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(URL);
StringEntity se;
se = new StringEntity(jsonObjSend.toString());
// Set HTTP parameters
httpPostRequest.setEntity(se);
httpPostRequest.setHeader("Accept", "application/json");
httpPostRequest.setHeader("Content-type", "application/json");
long t = System.currentTimeMillis();
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-t) + "ms]");
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream instream = entity.getContent();
// convert content stream to a String
String resultString= convertStreamToString(instream);
instream.close();
resultString = resultString.substring(1,resultString.length()-1); // remove wrapping "[" and "]"
jsonObjRecv = new JSONObject(resultString);
// Raw DEBUG output of our received JSON object:
Log.i(TAG,"<JSONObject>\n"+jsonObjRecv.toString()+"\n</JSONObject>");
}
}
catch (Exception e) {
e.printStackTrace();
}
return jsonObjRecv;
}
protected void onPostExecute(JSONObject result) {
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}else {
tv.setText("");
}
}
}
Then you call your async in onclik method like this:
public void onClick(View arg0) {
//.......
GetJsonTask client = new GetJsonTask(url, jRegister);
client.execute();
}
One problem in your code is that your expectations of AsyncTask aren't quite right. In particular this function:
public JSONObject getJSONFromUrl() {
this.execute();
return result;
}
AsyncTask runs the code in the doInBackground() function in a separate thread. This means that once you call execute() you have two parallel lines of execution. You end up with what's called a Race Condition. When you reach the return result line, a couple of things can be happening:
doInBackground() hasn't run and therefore result is still has the default value. In this case null.
doInBackground() can be in the middle of the code. In your particular case because it doesn't modify result then this doesn't affect you much. But it could be on any line (or middle of a line sometimes if operations aren't atomic) when that return happens.
doInBackground() could've finished, but since onPostExecute() runs on the UI thread it has to wait until your onClick handler is finished. By the time onPostExecute() has a chance to run onClick already tried to update tv with whatever it was that getJSONFromUrl returned, most likely null.
The way to set up tasks with AsyncTask is to give it the information it needs to do it's work, start it up with execute, and since you can't know how long it will take to complete, let it handle the finishing steps of the task.
This means that after calling execute you don't wait around for it's result to update views (like in your case), but rather rely on the AsyncTask's onPostExecute or related methods to take over the next steps.
For your case this would mean that your onPostExecute should look something like:
protected void onPostExecute(JSONObject result) {
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}

What is the most efficient way on Android to call HTTP Web API calls that return a JSON response?

I'm the perfectionist type, I already got web API calls working fine with Google Places API (just as an example), but I feel it's sometimes slow or maybe I'm not doing it right. Some blogs are saying I should use AndroidHttpClient, but I'm not, should I ?
The web API calls i'm using return json and I don't run them on the UI thread, hence using AsyncTask (is AsyncTask the most efficient way to run on background thread or should I use something else ?)
Please see my code and tell me how could it be more efficient in anyway
public static class NearbySearchRequest extends AsyncTask<String, Void, JSONObject>
{
Exception mException = null;
#Override
protected void onPreExecute()
{
super.onPreExecute();
this.mException = null;
}
#Override
protected JSONObject doInBackground(String... params)
{
StringBuilder urlString = new StringBuilder();
urlString.append("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
urlString.append("key=").append(Constants.GOOGLE_SIMPLE_API_KEY);
urlString.append("&location=").append(params[0]);
urlString.append("&sensor=").append("true");
urlString.append("&language=").append("en-GB");
urlString.append("&name=").append(params[1]);
urlString.append("&rankby=").append("distance");
LogHelper.Log(urlString.toString());
HttpURLConnection urlConnection = null;
URL url = null;
JSONObject object = null;
try
{
url = new URL(urlString.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
InputStream inStream = null;
inStream = urlConnection.getInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));
String temp, response = "";
while ((temp = bReader.readLine()) != null)
response += temp;
bReader.close();
inStream.close();
urlConnection.disconnect();
object = (JSONObject) new JSONTokener(response).nextValue();
}
catch (Exception e)
{
this.mException = e;
}
return (object);
}
#Override
protected void onPostExecute(JSONObject result)
{
super.onPostExecute(result);
if (this.mException != null)
ErrorHelper.report(this.mException, "Error # NearbySearchRequest");
}
}
The Http engine you're using seems the best choice. Actually any other 3-rd party engines are based either on Apache, either on HttpUrlConnection. I prefer to use Spring for Android as that API provide an abstraction over Http Engine and you don't really need to care how about what API to use based on API level. Or you can use Volley - a very fashionable library.
I would touch however some of your code:
What if there is an exception while reading the stream? Then the stream remains open and also the connection. So I would suggest to have a finally block where the streams and connection is closed no matter if you get an exception or not:
HttpURLConnection urlConnection = null;
URL url = null;
JSONObject object = null;
InputStream inStream = null;
try {
url = new URL(urlString.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
inStream = urlConnection.getInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));
String temp, response = "";
while ((temp = bReader.readLine()) != null) {
response += temp;
}
object = (JSONObject) new JSONTokener(response).nextValue();
} catch (Exception e) {
this.mException = e;
} finally {
if (inStream != null) {
try {
// this will close the bReader as well
inStream.close();
} catch (IOException ignored) {
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}
JSON parsing: you're using the Android standard way of parsing JSON, but that's not the fastest and easiest to work with. GSON and Jackson are better to use. To make a comparison when it comes for JSON parsers, I would go for Jackson. Here's another SO topic on this comparison.
Don't concatenate strings like that as concatenating strings will create each time another string. Use a StringBuilder instead.
Exception handling (this is anyway a long-debate subject in all programming forums). First of all you have to log it (Use Log class not System.out.printXXX). Then you need to either inform the user: either you toast a message, either you show a label or notification. The decision depends on the user case and how relevant is the call you're making.
These are the topics I see in you code.
EDIT I realize I didn't answer this: is AsyncTask the most efficient way to run on background thread or should I use something else?
The short answer I would give is: if you're supposed to perform a short time lived request, then AsyncTask is perfect. However, if you need to get some data and display it - but you don't want to worry about whether to download again if the screen is rotated and so on, I would strongly recommend using an AsyncTaskLoader and Loaders in general.
If you need to download some big data, then either you use an IntentService or, for heavy-weight operations, DownloadManager.
Enjoy coding!
------Create a Service Handler Class to your Project--------
public class ServiceHandler {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
public ServiceHandler() {
}
/*
* Making service call
* #url - url to make request
* #method - http request method
* */
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/*
* Making service call
* #url - url to make request
* #method - http request method
* #params - http request params
* */
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
Log.e("in POST","in POST");
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
Log.e("in POST params","in POST params");
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
Log.e("url in post service",url);
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
Log.e("in GET","in GET");
if (params != null) {
Log.e("in GET params","in GET params");
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
Log.e("url in get service",url);
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
public String makeServiceCallIMAGE(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
--------------AsyncTask For Login------------------
public class Login_Activity extends ActionBarActivity {
//Internet Service
NetworkConnection nw;
ProgressDialog prgDialog;
Boolean netConnection = false;
//
//Login API
String loginURL ="url";
//
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
nw = new NetworkConnection(getApplicationContext());
prgDialog = new ProgressDialog(this);
// Set Cancelable as False
prgDialog.setCancelable(false);
new LoginOperation().execute();
}
private class LoginOperation extends AsyncTask<String, Void, Void> {
String status, message;
#Override
protected void onPreExecute() {
// Set Progress Dialog Text
prgDialog.setMessage("Logging...");
prgDialog.show();
}
#Override
protected Void doInBackground(String... urls) {
if(nw.isConnectingToInternet() == true)
{
try
{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("method", "ClientesLogin"));
nameValuePairs.add(new BasicNameValuePair("Email", str_Email));
nameValuePairs.add(new BasicNameValuePair("Senha", str_Password));
ServiceHandler sh = new ServiceHandler();
String response = sh.makeServiceCall(loginURL, ServiceHandler.GET,
nameValuePairs);
Log.e("response", response);
JSONObject js = new JSONObject(response);
status = js.getString("status");
Log.e("status",status);
if(status.contains("Fail"))
{
message = js.getString("message");
}
/*else
{
JSONObject jslogin=js.getJSONObject("user_list");
for (int i = 0; i < jslogin.length(); i++) {
}
}*/
}catch(Exception ex){
}
netConnection = true;
}else
{
netConnection = false;
}
return null;
}
#Override
protected void onPostExecute(Void result) {
prgDialog.dismiss();
if(netConnection == false)
{
Toast toast = Toast.makeText(getApplicationContext(),"Internet is not available. Please turn on and try again.", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
else
{
if(status.contains("Success"))
{
Toast toast = Toast.makeText(getApplicationContext(), "Login Successful", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
Intent i=new Intent(Login_Activity.this,home_page_activity.class);
startActivity(i);
}
else{
Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
super.onPostExecute(result);
}
}
}
---------------Network Connection class---------------------
public class NetworkConnection {
Context context;
public NetworkConnection(Context context){
this.context = context;
}
public boolean isConnectingToInternet(){
ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null)
{
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED)
{
return true;
}
}
return false;
}
}
JSONArray main1 = js.getJSONArray("Test 1");
for (int i = 0; i < main1.length(); i++) {
JSONObject jsonObject = main1.getJSONObject(i);

IOException: Internal Server Error when trying to consume rest service

I want to create a restful web service in java using jersey API and consume it in android application. I got this question on SO but it talks about java client whereas I have android client.
My service looks like this:
#Path("/no")
public class CheckNumber {
#POST
#Produces("application/json")
#Consumes("application/json")
public String getDetails(#PathParam("cNo") String cNo) {
String CardNo="";
try {
JSONObject jsonObj = new JSONObject(cNo);
CardNo=jsonObj.getString("CardNo");
} catch (ParseException e1) {
e1.printStackTrace();
}
//Do something
return "someValue";
}
}
Now comes the client side:
public class MainActivity extends Activity {
JSONObject json = new JSONObject();
String wsdl = "http://192.168.1.105:8080/restdemo/check/no/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new RequestTask().execute("1234567890");
}
class RequestTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String add = "{\"CardNo\":\"" + uri[0] + "\"}";
HttpPost postMethod = new HttpPost(wsdl);
String responseString = null;
try {
postMethod.addHeader("Content-Type", "application/json");
HttpEntity entity = new StringEntity(add);
postMethod.setEntity(entity);
response = httpclient.execute(postMethod);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
}
I'm just starting with rest web services. I successfully created a sample rest service which consumes string and returns string and used this service in android app.
But when I try to pass json string using POST method. It's giving following errorin log:
java.io.IOException: Internal Server Error
at com.example.restclient.MainActivity$RequestTask.doInBackground(MainActivity.java:85)
where MainActivity.java:85 is throw new IOException(statusLine.getReasonPhrase()); which implies that statusLine.getStatusCode() is not returning HttpStatus.SC_OK. Instead it's returning status code = 500.
Any help appreciated.
It will be good to see the server side log to understand better.
Try creating the entity with UTF8 and set the content-type in the string entity rather than in the postMethod
StringEntity stringEntity = new StringEntity(myJsonDocStr, HTTP.UTF_8);
stringEntity.setContentType("application/json");
Try this code, It works for me
Boolean NetworkLostFlag = false;
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 10000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
int timeoutSocket = 12000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost(strUrl");
try {
httppost.setEntity(new UrlEncodedFormEntity(new BasicNameValuePair(arg1, val1), "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
try {
// do something useful
StringBuffer buffer = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = instream.read(b)) != -1;) {
buffer.append(new String(b, 0, n));
}
result = buffer.toString();
} catch (Exception e) {
NetworkLostFlag = true;
// TODO: handle exception
} finally {
instream.close();
}
}
} catch (Exception e) {
NetworkLostFlag = true;
e.printStackTrace();
}

Android: send post that has no response

In my app, I need to send all sorts of POST requests to a server. some of those requests have responses and others don't.
this is the code I'm using to send the requests:
private static final String TAG = "Server";
private static final String PATH = "http://10.0.0.2:8001/data_connection";
private static HttpResponse response = null;
private static StringEntity se = null;
private static HttpClient client;
private static HttpPost post = null;
public static String actionKey = null;
public static JSONObject sendRequest(JSONObject req) {
try {
client = new DefaultHttpClient();
actionKey = req.getString("actionKey");
se = new StringEntity(req.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING, "application/json"));
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post = new HttpPost(PATH);
post.setEntity(se);
Log.d(TAG, "http request is being sent");
response = client.execute(post);
Log.d(TAG, "http request was sent");
if (response != null) {
InputStream in = response.getEntity().getContent();
String a = convertFromInputStream(in);
in.close();
return new JSONObject(a);
}
} catch (UnsupportedEncodingException e) {
Log.d(TAG, "encoding request to String entity faild!");
e.printStackTrace();
} catch (ClientProtocolException e) {
Log.d(TAG, "executing the http POST didn't work");
e.printStackTrace();
} catch (IOException e) {
Log.d(TAG, "executing the http POST didn't work");
e.printStackTrace();
} catch (JSONException e) {
Log.d(TAG, "no ActionKey");
e.printStackTrace();
}
return null;
}
private static String convertFromInputStream(InputStream in)
throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return (sb.toString());
}
This is the code for the AsyncTask class that sends the request:
class ServerRequest extends AsyncTask<JSONObject, Void, JSONObject> {
#Override
protected JSONObject doInBackground(JSONObject... params) {
JSONObject req = params[0];
JSONObject response = Server.sendRequest(req);
return response;
}
#Override
protected void onPostExecute(JSONObject result) {
// HANDLE RESULT
super.onPostExecute(result);
}
}
my problem starts when the server doesn't return a response. the AsyncTask thread stays open even after the work is done because the HTTPClient never closes the connection.
Is there a way to not wait for a response? this is something that will definitely add a lot of overhead to the server since all the Android apps trying to connect to it will keep the connection alive, and will probably cause many problems on the app itself.
Basically, what I'm looking for is a method that will allow me to send to POST message and kill the connection right after the sending of the request since there is no response coming my way.
Just, Set ConnectionTimeOut with HttpClient Object, (Code is for your understanding in your case it may be different)
int TIMEOUT_MILLISEC = 30000;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_MILLISEC);
HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
HttpClient httpclient = new DefaultHttpClient(httpParams);
HttpPost httppost = new HttpPost(url);
httppost.addHeader("Content-Type", "application/json");
Now, It will terminate the Connection after TimeoOut you defined. But be sure this will throw TimeOutException so You have to handle this exception in your HttpRequest.. (Use Try -catch)
EDIT: Or you can use HttpRequestExecutor class.
From class HttpRequestExecutor of package org.apache.http.protocol
protected boolean canResponseHaveBody (HttpRequest request, HttpResponse response)
Decide whether a response comes with an entity. The implementation in this class is based on RFC 2616. Unknown methods and response codes are supposed to indicate responses with an entity.
Derived executors can override this method to handle methods and response codes not specified in RFC 2616.

Categories