I want to get XML data from the web server https://ruralfire.qld.gov.au/bushfirealert/bushfireAlert.xml
However, I can't do it because my codes always have an error "javax.net.ssl.SSLHandshakeException: Connection closed by peer".
And my InputStream is always null, so I can't do anything with it (such as parsing).
I ensure that the problem is in my connection but I don't know how to solve it.
This is my code in connecting to the web server:
private InputStream downloadUrl(String urlString) throws IOException {
URL url;
url = new URL(urlString);
InputStream is = null;
try {
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setDoInput(true);
is = con.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
May you help me to solve this problem ?
Thank you so much.
Related
I'm following an example of using the Reddit API in an Android app. I'm using Android Studio and Java. I have a link which returns a JSON object on a GET request (let's say http://www.reddit.com/r/dragonforce/.json), and the tutorial has this piece of code:
public static HttpURLConnection getConnection(String url){
System.out.println("URL: "+url);
HttpURLConnection hcon = null;
try {
hcon=(HttpURLConnection) new URL(url).openConnection();
hcon.setReadTimeout(30000); // Timeout at 30 seconds
hcon.setRequestProperty("User-Agent", "Alien V1.0");
} catch (MalformedURLException e) {
Log.e("getConnection()",
"Invalid URL: "+e.toString());
} catch (IOException e) {
Log.e("getConnection()",
"Could not connect: "+e.toString());
}
return hcon;
}
and
public static String readContents(String url){
HttpURLConnection hcon=getConnection(url);
if(hcon==null) return null;
try{
StringBuffer sb=new StringBuffer(8192);
String tmp="";
BufferedReader br=new BufferedReader(
new InputStreamReader(
hcon.getInputStream()
)
);
tmp = br.readLine();
while(tmp !=null) {
sb.append(tmp).append("\n");
tmp = br.readLine();
}
br.close();
return sb.toString();
}catch(IOException e){
Log.d("READ FAILED", e.toString());
return null;
}
}
I separated the tmp assignment for debug purposes. The problem is that nothing is read from the inputStream, and it returns an empty buffer to the JSONObject parser, resulting in JSONException end of input at character 0 of. I have user-permission in the Manifest for INTERNET, and the syntax for reading from the URL seems to be backed up by other sources on the internet, but it still seems something is amiss. Any help would be appreciated.
For anyone who is reading this down the line, the problem was that the URL in the tutorial was using HTTP instead of HTTPS, leading to a redirect response code and wasn't returning anything.
I have a trouble with my HttpsConnection on android.
First of all, no it is not a duplicate. I try almost all the solutions on SO, like changing the keep-alive option or the timeout ( and some of them indeed optimized a part of my code a little bit ) but it is still 5 to 10 times ( probably more ) slower on android than on iOS.
Sending a request to my server takes several seconds on android while it's almost instant on iOS and from a browser. I am sure that the server is not in cause. But it seems that getting the inputstream is terribly slow!
This line:
in=conn.getInputStream();
is the most delaying one, taking several seconds by itself.
My aim is to get a JSON from my server. My code is supposed to be technically as optimized as possible ( and it can probably help some people with HttpsConnection on the same time ):
protected String getContentUrl(String apiURL)
{
StringBuilder builder = new StringBuilder();
String line=null;
String result="";
HttpsURLConnection conn= null;
InputStream in= null;
try {
URL url;
// get URL content
url = new URL(apiURL);
System.setProperty("http.keepAlive", "false");
trustAllHosts();
conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(DO_NOT_VERIFY);
conn.setRequestMethod("GET");
conn.setRequestProperty(MainActivity.API_TOKEN, MainActivity.ENCRYPTED_TOKEN);
conn.setRequestProperty("Connection", "close");
conn.setConnectTimeout(1000);
in=conn.getInputStream();
// open the stream and put it into BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while ((line=br.readLine())!= null) {
builder.append(line);
}
result=builder.toString();
//System.out.print(result);
br.close();
} catch (MalformedURLException e) {
result=null;
} catch (IOException e) {
result=null;
} catch (Exception e) {
result=null;
}
finally {
try {
in.close();
}catch(Exception e){}
try {
conn.disconnect();
}catch(Exception e){}
return result;
}
}
However, it keeps taking several seconds.
So I would like to know: is there a way to improve the speed of this API call? The problem is not the server or the JSON parsing but for sure the function above. Thanks a lot.
For my application I need to have the latest data from an webpage that is hosted on a server on my local network.
So I request the latest page with a HTTP GET and when the data is received, I send another request.
With my current implementation I reach around the 100 - 120 ms per request. Is there a possibility to make this quicker because it's the same url that is requested.
For example keep the connection open to the page and grep the latest data without setting up a new connection?
This page is around the 900-1100 bytes.
HTTP get code:
public static String makeHttpGetRequest(String stringUrl) {
try {
URL url = new URL(stringUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(300);
con.setConnectTimeout(300);
con.setDoOutput(false);
con.setDoInput(true);
con.setChunkedStreamingMode(0);
con.setRequestMethod("GET");
return readStream(con.getInputStream());
} catch (IOException e) {
Log.e(TAG, "IOException when setting up connection: " + e.getMessage());
}
return null;
}
Reading inputstream
private static String readStream(InputStream in) {
BufferedReader reader = null;
StringBuilder total = new StringBuilder();
try {
String line = "";
reader = new BufferedReader(new InputStreamReader(in));
while ((line = reader.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
Log.e(TAG, "IOException when reading InputStream: " + e.getMessage());
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return total.toString();
}
As I know there isn't an implementation like you are asking for. I've been dealing a lot with http requests and the best thing you can do is your code. There is another thing which need some attention...your connection maybe slow and depending on that connection time can be more or in some cases which I've been dealing a lot the connection's timeout isn't enough big, but that's server problem.
In my opinion you should use what you have now.
I want to know if a specific file exists a on server or not. For example, suppose I have an .xml file on my server and I want to know if the file is there or not through java from my android application.
What server is it? If its HTTP server, you can request that file and check from response if it exist. If its custom server you have to implement that feature yourself.
You could use something like this:
URL url = null;
URLConnection connection = null;
InputStreamReader stream = null;
// Parse the URL
try {
url = new URL(urlString);
} catch (MalformedURLException e1) {
System.out.println("Malformed URL");
return null;
}
// Open a connection to the URL
try {
connection = url.openConnection();
} catch (IOException e) {
System.out.println("Could not create connection");
return null;
}
// Get the remote file
try {
stream = new InputStreamReader(connection.getInputStream());
} catch (IOException e) {
System.out.printf("File \"%s\" does not exist!",urlString);
return null;
}
I'm trying to parse an xml file from a website. Let's say the website is "http://example.com"
This website has a htaccess rewrite rule setup to redirect anything with a "www" prefix to the host back to example.com. so "http://www.example.com" would redirect to "http://example.com"
In my code I have a URL that i get the InputStream of.
protected InputStream getInputStream() {
try {
return feedUrl.openConnection().getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
In this case feedUrl is poingting to "http://www.example.com/file.xml" and when I do the following:
try {
Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
throw new RuntimeException(e);
}
I get an exception thrown and I believe it's not redirecting to "http://example.com/file.xml"
I could obviously just statically change where my feedUrl variable is pointing to, but I need this to be dynamic.
If anyone ran into this problem like I did, then here's the solution. The HttpURLConnection is already setup to follow redirects by default if the response code is 300, 301, 302, or 303.
For some reason, the server I'm parsing from needs to have the response code be 307 which Android does not redirect automatically.
I would suggest using a different response code, but if your server needs it then here's work around.
HttpURLConnection conn = (HttpURLConnection) feedUrl.openConnection();
int responseCode = conn.getResponseCode();
if( responseCode == 307 ){
String location = conn.getHeaderField("location");
feedUrl = new URL(location);
conn = (HttpURLConnection) this.feedUrl.openConnection();
}
Now conn can open an input stream to the correct file.