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.
Related
I wrote a program that fetches data from the Internet.
public class GetDataService {
public List<String> getData() {
List<String> lines = new ArrayList<>();
try {
URL url = new URL("http://worldtimeapi.org/api/ip.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
String a = line;
lines.add(a);
}
bufferedReader.close();
} catch (IOException ex) {
throw new RuntimeException("Can not making the request to the URL.");
}
return lines;
}
}
Now I want to test network error by using Mockito. How can I do it? Also, is my code good? Any suggestions to improve it?
You can do it this way :
when(mockUsingNetwork.doSomeNetworkAction()).thenReturn(new SomeNetworkError());
SomeNetworkError such as ConnectException for sockets for example
for your case it will be some thing like :
URL url = Mockito.mock(URL.class);
when(url.openConnection()).thenThrow(new IOException());
I want to get an HTML from a web page, remove some tags from the code and display it using a TextView... But those HTMLs are too big to be temporaly stored into a String...
When I try this way:
String html = "myBigHTML";
myTextView.setText(fromHtml(html));
compiler says error: constant string too long
If I put the html into a .txt and try this way:
InputStream is = getAssets().open("html.txt");
tvTeste.setText(fromHtml(convertStreamToString(is)));
public static String convertStreamToString(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
}
It works but the app gets soooo slow, almost freezes... And also, if I store it in a .txt I couldn't work with the tags...
.:: EDIT ::.
My onCreate() method as asked...
private TextView tvTeste;
private InputStream is;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_frequencia);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
tvTeste = (TextView)findViewById(R.id.tvTeste);
try {
is = getAssets().open("html.txt");
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String strLine;
List<String> stringList = new ArrayList<>();
try {
while ((strLine = br.readLine()) != null) {
stringList.add(strLine);
}
} catch (Exception e) {
e.printStackTrace();
}
tvTeste.setText(fromHtml(TextUtils.join("",stringList)));
}
Let's try this: each line of HTML text is a String. Each String is inside a List of String.
So, some pseudocode:
List<String> stringList = new ArrayList<>();
while (htmlHandler.next()) {
stringList.add(fromHtml(htmlHandler.readLine()));
}
myTextView.setText(joinStringArray(stringList));
Where joinStringArray uses a StringBuilder to produce a single big String object.
Basically you shouldn't read the entire web page, but you should read it sequentially.
Another point to mark. You should avoid any time consuming process that blocks the activity. try the same using, for example an AsyncTask.
Please check https://developer.android.com/reference/android/os/AsyncTask.html
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()
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.
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.