I use the class HttpURLConnection , but Iam confused with some methods
assume the HttpURLConnection object name is "c"
removing c.connect() will result in a success connection and it will retrieve the connection result without any problem
the output of c.getInputStream() and (InputStream) c.grtContent() are identical , so what is the difference betqween them
using HttpGet will reach the same approach as HttpURLConnection , so what is the difference between the two methods
what are the extra benefits for HttpURLConnection on URLConnection
c = (HttpURLConnection) (URL).openConnection();
c.connect(); //adding or removing makes the same result , so what is the usage of this method
InputStream stream= c.getInputStream();
InputStream stream2 = (InputStream) c.getContent();
//stream and stream2 are identical , so what is the differece between getInputStream() and getContent()
//============================
HttpGet c= new HttpGet(url);
HttpResponse response = c.execute(httpGet)
InputStream stream3 = response.getEntity().getContent();
//also stream3 is the same as stream & stream2 ; so how dose it different between HttpGet & HttpURLConnection
From Android documentation:
[HttpURLConnection is] A URLConnection with support for HTTP-specific features.
For instance, from an HttpURLConnection you can retrieve the HTTP method or the HTTP status code, which are HTTP-specific.
The URLConnection class, instead, is:
The abstract class URLConnection is the superclass of all classes that represent a communications link between the application and a URL
The normal usage is:
Create a URL object
Get a URLConnection by calling url.openConnection(). The returned object can be casted to an HttpURLConnection
get an InputStream by calling the connection.getInputStream() method
Close the connection (disconnect() method) (see #EJP comments)
Concerning the connect() method, from the Oracle documentation:
You are not always required to explicitly call the connect method to initiate the connection. Operations that depend on being connected, like getInputStream, getOutputStream, etc, will implicitly perform the connection, if necessary.
The difference between the HttpGet and HttpURLConnection is that they belong to 2 different libraries, but functionally they are more or less the same (now HttpGet has been deprecated and removed, so you won't find it in the standard Android APIs)
Related
I've looked at multiple posts with this issue, and most/all of them have code that tries to create an inputstream before an outputstream. I get that. I didn't think I was doing that here. Where is my inputstream being created before the error?
URL url = new URL(myURL);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
// Grab, configure json input as myInput
// ...
byte[] input = myInput.getBytes();
conn.connect();
// Write as post body
try(OutputStream os = conn.getOutputStream()) {
os.write(input); // <-- java.net.ProtocolException Error "Cannot write output after reading input" here
}
// Attempt to read response using InputStream
// ...
From the documentation of URLConnection::connect()
Opens a communications link to the resource referenced by this URL, if such a connection has not already been established.
If the connect method is called when the connection has already been opened (indicated by the connected field having the value true), the call is ignored.
URLConnection objects go through two phases: first they are created, then they are connected. After being created, and before being connected, various options can be specified (e.g., doInput and UseCaches). After connecting, it is an error to try to set them. Operations that depend on being connected, like getContentLength, will implicitly perform the connection, if necessary
So basically you're requiring to write in the OutputStream after you have manually opened the connection to the resource, without taking care of which flags or settings are set on that process. That won't work.
Actually, you shouldn't even call the method connect() by yourself, since the methods that depend on being connected, like getInputStream() and getOutputStream() already will perform the connection if they need to.
Remove the line conn.connect().
SocketAddress proxy = new InetSocketAddress("127.0.0.1", 8080);
URL url = new URL("http://192.168.1.1/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection(new Proxy(Proxy.Type.HTTP, proxy));
connection.setDoOutput(true);
String body = "This is a body example";
OutputStreamWriter writer = new OutputStreamWriter(new BufferedOutputStream(connection.getOutputStream()), "8859_1");
writer.write(body);
writer.flush();
writer.close();
connection.connect();
The problem is that when I run this code no requests are "catched" by my proxy (it is well configured). I know connect() is an abstract method in URLConnection but given that HttpURLConnection is extending URLConnection it is suppose to override it. This is what javadoc say about connect() : "Opens a communications link to the resource referenced by this URL, if such a connection has not already been established." So the request should have been sent. Anyone know what causes the problem?
NOTE : If I replace connection.connect() with connection.getResponseHeader() I catch a request. As I have read in javadoc if the connection is not set yet a call to getResponseHeader() will call implicitly the connect() method.
This is what javadoc say about connect() : "Opens a communications link to the resource referenced by this URL, if such a connection has not already been established."
Correct.
So the request should have been sent.
Non sequitur. Thwre is nothing in your quotation about sending the request.
As you have observed, the request is buffered until you perform some input step.
I am trying to read HTTP response using the HTTPUrlConnection in Android.
The getcontent() method of HTTPUrlConnection says it returns "Object" representing the content. What type of object is this? It's just saying "object" which I believe is the root object. What method can I
use to extract the contents?
Also, Instead if I use getInputStream() of HTTPUrlConnection and start reading it's contents, will it give me the data staring right from the headers or from the content?
Thanks.
With getInputStream() you will receive the whole page including headers and so on.
Exaple from: http://developer.android.com/reference/java/net/HttpURLConnection.html
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
finally {
urlConnection.disconnect();
}
}
With getContent() you get an normal Java Object thats right. I think u can cast it to a String and so get it's content.
I've read lots and tried lots relating to HTTP POSTS using HttpURLConnection and almost everything I come across has a similar structure which starts with these 3 lines:
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
When I try this I always get a "Connection Already Established" exception when calling setRequestMethod, which makes perfect sense as I'm clearly calling openConnection before setting the request type. Although reading the docs openConnection doesn't actually open the connection in theory.
There are several posts about this problem on SO such as this and this. I don't understand however why every piece of advice about how to write this code has these 3 lines in this order.
I'm guessing this code must work in most instances as someone must have tested it, so why doesn't this code work for me? How should I be writing this code?
I am aware these are other libraries I can use out there, I'm just wondering why this doesn't work.
Why the suspect code in the question has been duplicated all over the internet is something I can't answer. Nor can I answer why it seems to work for some people and not others. I can however answer the other question now, mainly thanks to this link that Luiggi pointed me to.
The key here is understanding the intricacies of the HttpURLConnection class. When first created the class defaults to a "GET" request method, so nothing needs to be changed in this instance. The following is rather unintuitive, but to set the request method to "POST" you should not call setRequestMethod("POST"), but rather setDoOutput(true) which implicitly sets the request method to post. Once you've done that you're good to go.
Below, I believe, is what a post method should look like. This is for posting json, but can obviously be altered for any other content type.
public static String doPostSync(final String urlToRead, final String content) throws IOException {
final String charset = "UTF-8";
// Create the connection
HttpURLConnection connection = (HttpURLConnection) new URL(urlToRead).openConnection();
// setDoOutput(true) implicitly set's the request type to POST
connection.setDoOutput(true);
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-type", "application/json");
// Write to the connection
OutputStream output = connection.getOutputStream();
output.write(content.getBytes(charset));
output.close();
// Check the error stream first, if this is null then there have been no issues with the request
InputStream inputStream = connection.getErrorStream();
if (inputStream == null)
inputStream = connection.getInputStream();
// Read everything from our stream
BufferedReader responseReader = new BufferedReader(new InputStreamReader(inputStream, charset));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = responseReader.readLine()) != null) {
response.append(inputLine);
}
responseReader.close();
return response.toString();
}
As per https://stackoverflow.com/a/3324964/436524, you need to call connection.setDoOutput(true) for it to expect a POST request.
This makes your code like this:
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
Is there any class for reading http pages that return a java.io.InputStream and its timeout be reliable?
I tried java.net.URLConnection and it doesn't have a reliable timeout (it takes more time that it set to timeout reach)? My Code is here:
URLConnection con = url.openConnection();
con.setConnectTimeout(2000);
con.setReadTimeout(2000);
InputStream in = con.getInputStream();
I expect that the reason that the timeout is not working for you is that you are setting the timeout after the connection has been established, or you are using the wrong setter. It is also possible that you are using "non-standard" version of URLConnection ...
"Some non-standard implementation of this method ignores the specified timeout. To see the read timeout set, please call getReadTimeout()." (or getConnectTimeout())
If you posted the relevant part of your actual code we could give you a better answer ...
Alternatively, use the Apache HttpClient library.
You can use Apache HttpClient to read http pages, it also has an http parser.check this for further reference about httpclient. you can get an InputStream object using their API like this.
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpGet httpget = new HttpGet("http://www.apache.org/");
// Execute the request
HttpResponse response = httpclient.execute(httpget);
// Examine the response status
System.out.println(response.getStatusLine());
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to worry about connection release
if (entity != null) {
InputStream instream = entity.getContent();
and coming to timeout part, it totally depends on the network and you cant do much about it from your java code.