I'm writing an Android app that should get data from a certain web application. That web app is based on Servlets and JSP, and it's not mine; it's a public library's service. What is the most elegant way of getting this data?
I tried writing my own Servlet to handle requests and responses, but I can't get it to work. Servlet forwarding cannot be done, due to different contexts, and redirection doesn't work either, since it's a POST method... I mean, sure, I can write my own form that access the library's servlet easily enough, but the result is a jsp page.. Can I turn that page into a string or something? Somehow I don't think I can.. I'm stuck.
Can I do this in some other way? With php or whatever? Or maybe get that jsp page on my web server, and then somehow extract data from it (with jQuery maybe?) and send it to Android? I really don't want to display that jsp page in a browser to my users, I would like to take that data and create my own objects with it..
Just send a HTTP request programmatically. You can use Android's builtin HttpClient API for this. Or, a bit more low level, the Java's java.net.URLConnection (see also Using java.net.URLConnection to fire and handle HTTP requests). Both are capable of sending GET/POST requests and retrieving the response back as an InputStream, byte[] or String.
At most simplest, you can perform a GET as follows:
InputStream responseBody = new URL("http://example.com").openStream();
// ...
A POST is easier to be performed with HttpClient:
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("name1", "value1"));
params.add(new BasicNameValuePair("name2", "value2"));
HttpPost post = new HttpPost("http://example.com");
post.setEntity(new UrlEncodedFormEntity(params));
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(post);
InputStream responseBody = response.getEntity().getContent();
// ...
If you need to parse the response as HTML (I'd however wonder if that "public library service" (is it really public?) doesn't really offer XML or JSON services which are way much easier to parse), Jsoup may be a life saver as to traversing and manipulating HTML the jQuery way. It also supports sending POST requests by the way, only not as fine grained as with HttpClient.
Related
Recently I started learning android. Now I want know information about web services in android.
which web services are fast in android?
we need to use any libraries for web service fastness?
My main aim is decrease the web service loading time.
Today I observed that web services are taking more time in below API levels and somewhat better in above API levels.
Please any one suggest me how to decrease web service loading.
If you think a library can be used then you may consider using Square Retrofit. With some benchmarks tested, it is quite snappy when considered with async task. Also you can take a look at volley which is also an option in this case but I would recommend Retrofit for its ease of use. you can consider the following article for some metrics.
Android Async HTTP Clients: Volley vs Retrofit.
JSON based web service is lightweight than XML or any other format so even in the low network connectivity you can expect considerable good performance.
Here is a sample code to connect with JSON based web service
JSONObject jsonObj = new JSONObject();
jsonObj.put("username", username);
jsonObj.put("data", dataValue);
// Create the POST object and add the parameters
HttpPost httpPost = new HttpPost(url);
StringEntity entity = new StringEntity(jsonObj.toString(), HTTP.UTF_8);
entity.setContentType("application/json");
httpPost.setEntity(entity);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(httpPost);
It's always better to make network calls inside AsyncTask so that you can show progress bar while you are dealing with web service
As of now, if I have to store something from Android to the server, I make an HTTP request of a GET URL, with data in the form of parameter values. On the server side, I use PHP to extract the parameter values and store them in database.
Similarly, if I want to get something from the server to Android, I post a JSON string on the webpage using PHP. Then I read it in Android using HTTP request, convert the string to JSON and then use the data.
This method of PHP-MySQL-Android-JSON is very easy but not secure. Suppose I want to store the score of player from my game in Android to the server's database, it is easy to execute some URL like www.example.com/save_score.php?player_id=123&score=999 from Android. But anyone can update his score if he comes to know the php file name and names of parameters, by simply typing this URL in a browser.
So what is the correct method of interacting with a server (my server supports PHP but not Java)?
I have heard about RESTful and KSOAP2, but know nothing about them. Can you please explain them a bit in lay man language (reading the proper definitions didn't help me)? What are these used for?
What is the best way to send score to the server? Any tutorial link would be great.
Thanks.
Edit 1:
I don't use proguard to obfuscate my code for several reasons. So anyone can reverse engineer the apk, look into the code, find the URL to update the score, write his own POST method and update his score. How can I stop this from happening?
Use POST method to post data from android and get it in php. e.g. use this method to send your data in json formate , which will not be showing in url.
public static String sendRequest(String value, String urlString) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(urlString);
httppost.setHeader( "Content-Type", "application/json");
//value = "";
StringEntity stringEntity = new StringEntity(value);
stringEntity.setContentEncoding("UTF-8");
stringEntity.setContentType("application/json");
httpclient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, System.getProperty("http.agent"));
httppost.setEntity(stringEntity);
HttpResponse response = httpclient.execute(httppost);
String responseString = convertStreamToString(response.getEntity().getContent());
return responseString;
} catch (Exception e) {
Log.d("check", ""+e.getMessage());
return ERROR_SERVICE_NOT_RESPONDE;
}
}
And call this method like this.
sendRequest({"player_id":1,"score":123}, "www.example.com/save_score.php");
And get json body in php and parse it.
I think you should read more documents about RESTful, Http POST and GET before starting. Your example url is GET method. It should be used for getting public information or query data. If you want to change something in server side, you should use POST method, it is more security than GET.
My recommend is using RESTful because it is painless than SOAP, especially for Android. Here is an example HTTP POST on Android.
I am trying to log into a site and load a webpage programatically in android. Meaning, I have the password and login and need to submit a webform and get the response page. I tried the code here: Doing HTTP Post with Android
but I think I may be doing it wrong.
If this is the site I'm trying to access: http://goo.gl/eiBhP
and my code is
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost(Constants.MAIN_URL);
List<namevaluepair> nameValuePairs = new ArrayList<namevaluepair>(2);
nameValuePairs.add(new BasicNameValuePair("username", "correctusername"));
nameValuePairs.add(new BasicNameValuePair("password", "correctpassword"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpost);
Then I should be able to use
BufferedReader br = new BufferedReader(new InputStreamReader(
entity.getContent()), 8096);
to get the response. The id of the login and pass on the site ate username and password. should I also somehow submit the button as a name value pair? I cant seem to get this to work, it just returns the login page. Please Help. I've tried reading over the other similar questions but I can't seem to get it to work.
Basically, you need to make sure that your code is submitting exactly the same information as the webpage.
As Selvin points out, there's a good chance that the website is using some form of tracking - be it in hidden input values, cookies or some other state-based data.
You need to look at the source of the login webpage and understand what it is doing when you submit login details - you don't necessarily need to know what all the values mean, but your code must submit the same POST data.
If the website is using state information, you won't be able to hard-code those input values in your code. You'll probably need to retrieve a new instance of the login webpage each time using a HTTP GET request and then parse the data to extract the relevant state data. Don't forget that they may also be using cookies which you may need to submit.
All in all, you probably need to do a lot more work to get it to a working state. Not trying to dissuade you (and I don't know what you're trying to achieve), but perhaps it's easier just to use the website!
I'm familiar with android HTTPURLConnection and apache HTTPConnection classes and the way they work (they are all synchronous, but I can live with that).
I have a large response with many lines of data comming from the server. It's a JSON response and I can display the data partially before I parsed all the response. Some json parsers allow that (like xcers allows for xml). Do the callbacks and methods related to the two classes mentioned above allow it? When I get the response from HTTPURLConnection upon opening input stream and read, do I open the stream when ALL the data is already there? Or can I open and read it and more that should follow?
Also, is there any http method on android that works with NIO?
With HttpClient, when you open the response stream like this:
HttpGet request = new HttpGet();
request.setURI(new URI(url));
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
and start reading, you actually start the downloading and you get new bytes as soon as these are received. You don't wait for everything to get downloaded to start reading.
As far as I know the HttpClient that is bundled with Android is not based on NIO. I don't know of any alternative that does so.
In addition to all of the possible solutions in Ladlestein's comment, there's the simple answer of wrapping all that in an AsyncTask. Here is a sample project demonstrating doing an HTTP request using HttpClient in an AsyncTask.
I've a application deployed on google app-engine..it has a registration form.
now i've made a registration form in my android application and i want that on click submit...it should be sent to the application on google app-engine and it should be persisted in the particular db...
somebody told me to use http request and response method but i'm not aware of that thing..
can somebody please provide me with some sample code or something.....
thanksss....
You haven't specified if you're using Python or Java.
You have to decide how you want to connect. At the simplest level you could just POST the data to Google App Engine. In Java you would write a servlet which handles this. See Java EE tutorial. Alternatively you could write a web service (SOAP, RESTful) on the server which handles the data being sent from your application. Again Google this and there are countless examples.
Assume we're going down the simplest POST route. So in your servlet (running on GAE) you'd have something like this:
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String value1 = request.getParameter("value1");
}
And in your android app you'd do something like:
DefaultHttpClient hc=new DefaultHttpClient();
ResponseHandler <String> res=new BasicResponseHandler();
HttpPost postMethod=new HttpPost("http://mywebsite.com/mappedurl");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("value1", "Value my user entered"));
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
String response=hc.execute(postMethod,res);
Of course value1 in the servlet would be set to "Value my user entered".
EDIT: Google have now released their Google Cloud Endpoints - this makes building RESTful services on App Engine and creating clients for Android a lot easier. It does tie you in to App Engine even more though - but certainly worthy of consideration.