Connecting to a webserver with android - android

I have to connect to a webserver from android and I have to access a webservice and a webpage from the webserver. Can anybody help me? Please give step by step process with some code snippets because I am new to android and I don't know anything in connecting to a webserver.

You can use an HttpClient:
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(uri);
HttpResponse httpResponse = httpClient.execute(httpGet);
BufferedReader reader = new BufferedReader(
new InputStreamReader(httpResponse.getEntity().getContent()));
// user reader to read & parse response
reader.close();
Parsing the response obviously depends on the format (e.g. SOAP, JSON, etc.)

You haven't given very much info (what kind of web page, XML/JSON/HTML/etc. ?). But the basic principles of regular Java apply. Using URL and InputStream:
URL url = new URL(...);
InputStream is = url.openStream();
And from there it depends what kind of data you're dealing with.

If you don't want to use an additional library, here is a means for sending an "id" and "name" to a server:
URL url = null;
try {
String registrationUrl = String.format("http://myserver/register?id=%s&name=%s", myId, URLEncoder.encode(myName,"UTF-8"));
url = new URL(registrationUrl);
URLConnection connection = url.openConnection();
HttpURLConnection httpConnection = (HttpURLConnection) connection;
int responseCode = httpConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
Log.d("MyApp", "Registration success");
} else {
Log.w("MyApp", "Registration failed for: " + registrationUrl);
}
} catch (Exception ex) {
ex.printStackTrace();
}
You could just as easily send other data via this URI "GET" style, but if you need to send something more detailed a POST will be required.
Note: Originally posted to answer a similar question here: How to connect android to server

Related

Get JSON from URL - deprecated method?

I have been using this code to get JSON from a specified URL, but today I checked it, and everything in it is deprecated. It still works fine, but I want to know what is the new method of doing it?
Here's what I have:
#Override
protected String doInBackground(String... params) {
try {
HttpClient client = new DefaultHttpClient();
StringBuilder url = new StringBuilder("some url");
HttpGet hg = new HttpGet(url.toString());
HttpResponse hr = client.execute(hg);
int status = hr.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity he = hr.getEntity();
String data = EntityUtils.toString(he);
jsonGet = new JSONObject(data);
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
The deprecated objects are HttpClient, HttpGet, HttpResponse, HttpEntity and EntityUtils.
EDIT: As suggested in some questions, this way
HttpClient client = HttpClientBuilder.create().build();
does not work for me, as I am getting HttpClientBuilder cannot be resolved
Apache httpClient is deprecated with api level 22 you can read it about this blog.
there is a new client for android now and it is very good.
but you can use okhttp instead (also back compat is possible).
EDIT
check this link(URL.openConnection()). this blog was posted in 2011 but they mentioned the deprecation there first as far as i know.
First of all you have to search well on Google.
Here is your answer may it will helps you.
The HttpClient documentation points you in the right direction:
org.apache.http.client.HttpClient:
This interface was deprecated in API level 22.
Please use openConnection() instead. Please visit this webpage for further details.
means that you should switch to java.net.URL.openConnection().
Here's how you could do it:
URL url = new URL("http://some-server");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
// read the response
System.out.println("Response Code: " + conn.getResponseCode());
InputStream in = new BufferedInputStream(conn.getInputStream());
String response = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
System.out.println(response);
IOUtils documentation: Apache Commons IO
IOUtils Maven dependency: http://search.maven.org/#artifactdetails|org.apache.commons|commons-io|1.3.2|jar
Special Thanks to fateddy for this answer

Android - How can I open a persistent HTTP connection that receives chunked responses?

I'm trying to establish a persistent HTTP connection to an API endpoint that publishes chunked JSON responses as new events occur. I would like to provide a callback that is called each time the server sends a new chunk of data, and keep the connection open indefinitely. As far as I can tell, neither HttpClient nor HttpUrlConnection provide this functionality.
Is there a way to accomplish this without using a TCP socket?
One solution would be to use a delimeter such as \n\n to separate each json event. You could remove blank lines from original json before sending. Calling setChunkedStreamingMode(0) allows you to read content as it comes in (rather than after the entire request has been buffered). Then you can simply go through each line, storing them, until a blank line is reached, then parse the stored lines as JSON.
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setChunkedStreamingMode(0);
conn.connect();
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringBuffer sBuffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
if (line.length() == 0) {
processJsonEvent(sBuffer.toString());
sBuffer.delete(0, sBuffer.length());
} else {
sBuffer.append(line);
sBuffer.append("\n");
}
}
As far as I can tell, Android's HttpURLConnection doesn't support receiving chunks of data across a persistent HTTP connection; it instead waits for the response to fully complete.
Using HttpClient, however, works:
HttpClient httpClient = new DefaultHttpClient();
try {
HttpUriRequest request = new HttpGet(new URI("https://www.yourStreamingUrlHere.com"));
} catch (URISyntaxException e) {
e.printStackTrace();
}
try {
HttpResponse response = httpClient.execute(request);
InputStream responseStream = response.getEntity().getContent();
BufferedReader rd = new BufferedReader(new InputStreamReader(responseStream));
String line;
do {
line = rd.readLine();
// handle new line of data here
} while (!line.isEmpty());
// reaching here means the server closed the connection
} catch (Exception e) {
// connection attempt failed or connection timed out
}

Android: Getting HTTP response incrementally like in iOS

I'm relatively new to Android (I'm an iOS-Developer) and I want to call a Webservice like I'm used to in iOS with NSURLConnectionDelegate's method
didReceiveData:(NSData *)data
I need to get the data incrementally because I'm building a streaming API that gets a lot of JSON data in response and needs to check the data for complete blocks.
Would be great if someone could help me, I've been searching for a while and didn't find a satisfying solution so far.
If you try to call web services in Android you should use the AsyncTask where the request would be made asynchronously. Have a look at the documentation. Every time you're request would be finished the method onPostExecute(Object result) would be called. Thats the method where you can go on with further processes.
The URLConnection documentation contain following example:
URL url = new URL("ftp://mirror.csclub.uwaterloo.ca/index.html");
URLConnection urlConnection = url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
try {
readStream(in);
finally {
in.close();
}
If i right understood your question, just implement readStream function as you need.
I found out how to do this with the help of a friend and some links.
You need to implement an own ResponseHandler like this:
class ChunkedResponseHandler implements ResponseHandler<String> {
#Override
public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
StringBuffer output = new StringBuffer();
byte[] b = new byte[4096];
int n;
while ((n = stream.read(b)) != -1) {
output.append(new String(b, 0, n));
// do something while input is streaming
}
return output.toString();
}
}
Now you simply have to assign the response handler when starting the request:
HttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet("someURL");
ResponseHandler<String> responseHandler = new ChunkedResponseHandler();
String responseBody = client.execute(postRequest, responseHandler);

Making large REST requests

I have a REST service I can't alter, with methods for uploading an image, encoded as a Base64 string.
The problem is that the images can go up to sizes of 5-10MB, perhaps more. When I try to construct a Base64 representation of an image of this size on the device, I get an OutOfMemory exception.
I can however encode chunks of bytes at a time (3000 let's say), but this is useless as I would need the whole string to create a HttpGet/HttpPost object:
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("www.server.com/longString");
HttpResponse response = client.execute(httpGet);
Is there a way of going around this?
Edit: trying to use Heiko Rupp's suggestions + the android doc, I get an exception ("java.io.FileNotFoundException: http://www.google.com") at the following line: InputStream in = urlConnection.getInputStream();
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
out.write("/translate".getBytes());
InputStream in = urlConnection.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(in));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
System.out.println("response:" + total);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Am I missing something? The GET request that I need to execute looks like this:
"http://myRESTService.com/myMethod?params=LOOONG-String", so the idea was to connect to http://myRESTService.com/myMethod and then output a few characters of the long string at a time. Is this correct?
You should try to use the URLConnection instead of the apache http client, as this does not require you to hold the object to send in memory, but instead you can do something like:
pseudocode!
HttpUrlConnection con = restUrl.getConnection();
while (!done) {
byte[] part = base64encode(partOfImage);
con.write (part);
partOfImage = nextPartOfImage();
}
con.flush();
con.close();
Also in Android after 2.2 Google recommends the URLConnection over the http client. See the description of DefaultHttpClient.
The other thing you may want to look into is the amount of data to be sent. 10 MB + base64 will take quite a while to transfer (even with gzip compression, which the URLConnection transparently enables if the server side accepts it) over a mobile network.
You must read docs for this REST service, no such service will require you to send such long data in GET. Images are always sent as POST. POST data is always at the end of request and allows to be added iteratively.

Why connection is not establishing on first time?

I want to send my id & password to server and get the response from server. Here is my code. It is not working for the first time. But iam getting the response from server if i execute my application on second time. It is throwing "Post method failed: -1 null" on first time. Where iam wrong?? Why if() block is executing on first time?? could you please tell me.
HttpsURLConnection con = null;
String httpsURL = "https://www.abc.com/login";
String query = "id=xyz&password=pqr";
URL url = new URL(httpsURL);
con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(query.length()));
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("User-Agent","Mozilla/4.0(compatible; MSIE 5.0; Windows 98; DigExt)");
con.setDoInput(true);
con.setDoOutput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(query);
output.close();
int respCode = con.getResponseCode();
if (respCode != HttpsURLConnection.HTTP_OK)
{
throw new Exception("POST method failed: " + con.getResponseCode()+ "\t" + con.getResponseMessage()); }
else {
//read the content from server
}
1/ It is recommanded to use apache HttpClient rather than URLConnection (see http://developer.android.com/reference/org/apache/http/impl/client/DefaultHttpClient.html)
2/ for login and password, why not use Http Authentication ? both basic and digest are supported by android.
3/ as for you problem, you don't close the underlying outputStream.
you should do:
OutputStream os = con.getOutputStream();
DataOutputStream output = new DataOutputStream(os);
output.writeBytes(query);
output.close();
os.close();
Check Server service validity with other technology and/or classic java. You didn say in your question if you succeed to discriminate the server from the issue.
from java doc ...getResponseCode returns -1 if no code can be discerned from the response (i.e., the response is not valid HTTP).
Java https post request example : http://www.java-samples.com/java/POST-toHTTPS-url-free-java-sample-program.htm
try to close your outputstream after querying the status and not before...that may help
Here is how you should send POST requests in Android
HttpPost httpGet = new HttpPost(server + "/login?email="+username+"&password="+password);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(httpGet);
You can read response using:
response.getEntity().getContent()

Categories

Resources