How to handle problem with Network Connectivity in Java - java

I have a simple java code which gets html text from the input url:
try {
URL url = new URL("www.abc.com");
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(url.openStream()));
while ((line = rd.readLine()) != null) {
String code = code + line;
} catch (IOException e){}
I am using this code in an android project. Now the problem comes when there is no internet connectivity. The application just halts and later gives error.
Is there some way to break this after some fixed timeout, or even return some specific string after an exception is thrown. Can you please tell me how to do that??

Try this:
try
{
URL url = new URL("www.abc.com");
String newline = System.getProperty("line.separator");
InputStream is = url.openStream();
if (is != null)
{
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
StringBuilder contents = new StringBuilder();
while ((line = rd.readLine()) != null)
{
contents.append(line).append(newline);
}
}
else
{
System.out.println("input stream was null");
}
}
catch (Exception e)
{
e.printStackTrace();
}
An empty catch block is asking for trouble.

I don't know what the default timeout is for URL, and a quick look at the javadocs doesn't seem to reveal anything. So try using HttpURLConnection directly instead http://download.oracle.com/javase/1.5.0/docs/api/java/net/HttpURLConnection.html. This lets you set timeout values:
public static void main(String[] args) throws Exception {
URL url = new URL("http://www.google.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000); // 5 seconds
conn.setRequestMethod("GET");
conn.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
conn.disconnect();
}
You can also set a read time out as well, as well as specify behaviour re redirects and a few other things.

I think in addition to timeouts it could be also smart to check the Internet availability right before the requesting:
public class ConnectivityHelper {
public static boolean isAnyNetworkConnected(Context context) {
return isWiFiNetworkConnected(context) || isMobileNetworkConnected(context);
}
public static boolean isWiFiNetworkConnected(Context context) {
return getWiFiNetworkInfo(context).isConnected();
}
public static boolean isMobileNetworkConnected(Context context) {
return getMobileNetworkInfo(context).isConnected();
}
private static ConnectivityManager getConnectivityManager(Context context) {
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
}
UPDATE: For timeouts see an excellent kuester2000's reply here.

Just a general tip on working with Streams always close them when they are no longer needed. I just wanted to post that up as it seems that most people didn't take care of it in their examples.

Related

Java read from URL stream working selectively

Summary: Sample Java code that reads over a URLConnection reads only certain URLs, not others.
Details: I have this sample Java code that I am using to read over a URLConnection. When the URL is "http://www.example.com", the code reads the page content without any issues. However, if the URL is "http://www.cnn.com", the page content is not read
public class StackOverflow {
public static void main(String[] args) throws Exception {
BufferedReader inputStream = null;
try {
String urlStr = "http://www.cnn.com"; // Does not work
// urlStr = "http://www.example.com"; // **Works if this line is uncommented**
URL url = new URL(urlStr);
inputStream = new BufferedReader(new InputStreamReader(url.openStream()));
String textLine = null;
while((textLine = inputStream.readLine()) != null) {
System.out.println(textLine);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(inputStream != null) inputStream.close();
}
}
}
CNN redirects from http to https but your call doesn't follow redirects. You are getting a 307 with an empty body so the readline results in a null and your loop is skipped. Try with https for CNN.

How to make http call from standalone java application

I'm making a small dictionary kind of app using java swings. I'm using oxford dictionary api for that. Is there any way to make a simple ajax request in java without using servelets and all advanced java concepts. As in android we use http url connection to do this job.I googled a lot for finding this but I could't find a solution as every page is showing results using servelets. But I know core java alone.If it is possible to make ajax call without servelts please help me...Thanks in advance...
Use HttpURLConnection class to make http call.
If you need more help for that then go for offical documentation site of java Here
Example
public class JavaHttpUrlConnectionReader {
public static void main(String[] args) throws IOException{
String results = doHttpUrlConnectionAction("https://your.url.com/", "GET");
System.out.println(results);
}
public static String doHttpUrlConnectionAction(String desiredUrl, String requestType) throws IOException {
BufferedReader reader = null;
StringBuilder stringBuilder;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(desiredUrl).openConnection();
connection.setRequestMethod(requestType);// Can be "GET","POST","DELETE",etc
connection.setReadTimeout(3 * 1000);
connection.connect();// Make call
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));// Reading Responce
stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
return stringBuilder.toString();
} catch (IOException e) {
throw new IOException("Problam in connection : ", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ioe) {
throw new IOException("Problam in closing reader : ", ioe);
}
}
}
}
}
It will make a call and give response as return string. If you want to make POST call the need to do some extra for that :
try{
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.write(postParam.getBytes());
} catch(IOException e){
}
Note : Here postParam is String type with value somthing like "someId=156422&someAnotherId=32651"
And put this porson befor connection.connect() statement.

Handling IOExceptions in Android

I'm creating an app where I need a function to get plain text from a website. I am able to get the text and print it out on my PC just fine, but when I try running it on an Android device, the app won't start.
I believe it has something to do with throwing an IOException. I've been reading that I am not supposed to do that because I don't define the interface. Is there a way to get around this? Android Studio won't compile my code if I don't throw the exception.
The function:
public String getText(String site) throws IOException {
// Make a URL to the web page
URL url = new URL(site);
// Get the input stream through URL Connection
URLConnection con = url.openConnection();
InputStream is =con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// read each line and return the final text
String res = "";
String line = null;
while ((line = br.readLine()) != null) {
//System.out.println(line);
res += line;
}
return res;
}
And this is how Android Studio makes me run it in the onCreate method:
String text = null;
try {
text = getText("http://myWebsite.com");
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
First, read your logcat - you should see your exception there with full stacktrace. Second, there is nothing wrong with catching IOException, but you must do something with it once cached - like inform user of problem in functionality - like no more space, etc.
And this is how Android Studio makes me run it in the onCreate method:
this is a problem, because your are getting data from your site on UI thread, you must do it from worker thread, ie. AsyncTask.
You can not do it in the main thread
try this
class MyTask extends AsyncTask<Void, Void, String>{
private String site;
MyTask(String site) {
this.site = site;
}
#Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(site);
URLConnection con = url.openConnection();
InputStream is =con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// read each line and return the final text
String res = "";
String line = null;
while ((line = br.readLine()) != null) {
//System.out.println(line);
res += line;
}
return res;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(s != null){
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
}
}
where to get a string is used as
new MyTask("http://myWebsite.com").execute()

Type mismatch: cannot convert from StringBuilder to String

This method returns the source of the given URL.
private static String getUrlSource(String url) {
try {
URL localUrl = null;
localUrl = new URL(url);
URLConnection conn = localUrl.openConnection();
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line = "";
String html;
StringBuilder ma = new StringBuilder();
while ((line = reader.readLine()) != null) {
ma.append(line);
}
return ma;
} catch (Exception e) {
Log.e("ERR",e.getMessage());
}
}
It gives me this error:
Type mismatch: cannot convert from StringBuilder to String
And two choices:
Change the return type to StringBuilder.
But I want it to return a String.
Change type of ma to String.
After changing a String has no append() method.
Just use
return ma.toString();
instead of
return ma;
ma.toString() returns the string representation for your StringBuilder.
See StringBuilder#toString() for details
As Valeri Atamaniouk suggested in comments, you should also return something in the catch block, otherwise you will get a compiler error for missing return statement, so editing
} catch (Exception e) {
Log.e("ERR",e.getMessage());
}
to
} catch (Exception e) {
Log.e("ERR",e.getMessage());
return null; //or maybe return another string
}
Would be a good idea.
EDIT
As Esailija suggested, we have three anti-patterns in this code
} catch (Exception e) { //You should catch the specific exception
Log.e("ERR",e.getMessage()); //Don't log the exception, throw it and let the caller handle it
return null; //Don't return null if it is unnecessary
}
So i think it is better to do something like that:
private static String getUrlSource(String url) throws MalformedURLException, IOException {
URL localUrl = null;
localUrl = new URL(url);
URLConnection conn = localUrl.openConnection();
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line = "";
String html;
StringBuilder ma = new StringBuilder();
while ((line = reader.readLine()) != null) {
ma.append(line);
}
return ma.toString();
}
And then, when you call it:
try {
String urlSource = getUrlSource("http://www.google.com");
//process your url source
} catch (MalformedURLException ex) {
//your url is wrong, do some stuff here
} catch (IOException ex) {
//I/O operations were interrupted, do some stuff here
}
Check these links for further details about Java Anti-Patterns:
Java Anti-Patterns
Programming Anti-Patterns
An Introduction to Antipatterns in Java Applications
I have same problem while converting StringBuilder to String, and i use above point but that's not give correct solution.
using above code output comes like this
String out=ma.toString();
// out=[Ljava.lang.String;#41e633e0
After that i find out correct solution.Think is create a new String instant inserted of StringBuilder like this..
String out=new String(ma);
try
return ma.toString();
as you can not directly store stringbuilder variable into a string variable.

searching for a string in a url

I'm trying to search for a particular string inside of my company's website in order to check that the website is alive.
Can you give me a hint on how to do this?
Here is my code so far:
public static void main(String[] args) throws Exception {
try {
URL oracle = new URL("http://10.200.10.199:80");
BufferedReader in = new BufferedReader(new InputStreamReader(
oracle.openStream()));
inputLine = in.readLine();
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
}
in.close();
} catch (IOException e) {
// TODO: handle exception
System.out.println("Page was not found - might not be running");
}
StringUtils from org.apache.commons.lang (Commons Lang) can do the job well for you.
boolean contains=false;
while ((inputLine = in.readLine()) != null)
{
contains = StringUtils.contains(inputLine, searchString);
}
You can rather use String.contains(CharSequence) too. CharSequence can be created easily by
CharSequence cs = searchString;
Sounds like regular expressions to me. Unless you know the string exactly, in which case you could just do String.indexOf on each line.

Categories

Resources