HttpURLConnection.getOutputStream() takes 20 seconds. Why? - java

I'm trying to perform webservice calls in android (2.3.4) using the following code snippet. My problem occurs on conn.getOutputStream, as this method seems to be taking a full 20 seconds to return. Any thoughts?
URL uri = new URL(serviceURI + "/remoteMethod");
HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
Log.d(TAG, "opening output stream");
OutputStreamWriter writer = new OutputStreamWriter(
conn.getOutputStream());
Log.d(TAG, "output stream opened");
String body = getRequestBody();
writer.write(body);
writer.flush();
writer.close();
int responseCode= conn.getResponseCode();

It would appear that this was probably a network problem, and that jarnbjo was actually correct in his suggestion in the comments that the connection was just taking too long. I moved the server and device to another network (webservice is not public), and the problem cleared up.

Related

Upload file on server using Rest API

I want to commit text file "demo2.txt" to bitbucket server using rest API. I can upload the same file using Postman but it's not working with Java code. As shown in the below code I want to send string object "str" as the body. Can someone help me here to upload the file on the bitbucket server? Also Please let me know if there is any other way to do this.
URL url = new URL("https://api.bitbucket.org/2.0/repositories/{team name}/{repository name}/src");
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setRequestProperty("X-Requested-with", "Curl");
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setRequestProperty("Connection", "Keep-Alive");
httpCon.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);
httpCon.setRequestProperty("Accept", "application/x-www-form-urlencoded");
httpCon.setRequestProperty("Authorization", basicauth);
httpCon.setRequestMethod("POST");
String str =
"{"
+ "\"-F\":\"File3=#/D:/log/demo2.txt\" "
+ "}";
try {
OutputStream output = httpCon.getOutputStream();
output.write(str.getBytes());
output.close();
} catch(Exception e){
System.out.println(e.getMessage());
}
int responseCode = httpCon.getResponseCode();
String inputLine;
StringBuffer response = new StringBuffer();
if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED){
BufferedReader in = new BufferedReader(new .
InputStreamReader(httpCon.getInputStream()));
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
List<String> message = new ArrayList<>();
message.add(response.toString());
}
If this is all of your code, then your problem may be as simple as the fact that you're not making any sort of call to finalize the request...to tell HttpURLConnection that you're done forming the request and want it to complete. There are two things you can do to help this:
close the output stream when you're done writing to it. You're generally supposed to do this. Here, you can call output.close(). Better still, since you have a try/catch block already anyway, use a "try with resources" construct to make sure that the stream is closed no matter what happens (assuming you're using a newer version of Java that supports this).
make some sort of call to query the response to the request. It may
be that the request is not being fully sent until you do this. Try
calling httpCon.getResponseCode() at the bottom of your code.
Given that you have provided no information as to what "it's not working with Java code" means, this may be useful information but not the ultimate solution to your problem. Your code does look good other than exhibiting these omissions.

Java HTTP connection seems to remain open

I have created a connection in Java to private API
String urlRequest = "https://localhost:8080/orders/create";
String username = "test";
String password = "test";
String certificatePass = "test";
byte[] authEncBytes = Base64.getEncoder().encode((username + ":" + password).getBytes());
URL url = new URL(urlRequest);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Basic " + new String(authEncBytes));
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
is.close();
After the initial pass, connection seems to remain open, because when running the code from the start, HttpURLConnection throws an Exception at conn.setRequestMethod("POST");,
"Can't reset method: already connected"
I managed to somehow close it now, I don't know what have I done, but does anyone know what the issue here could have been? I restarted my PC in the meantime, and it would still thrown an exception at conn.setRequestMethod("POST");, I don't understand how can a connection persist between restarts. I also tried adding conn.disconnect() before trying to set request method, and that didn't seem to work either. The only thing that made a difference was changing the URL, but I could only connect once, every next time running the code would give me the same exception.
How do I close the connection properly?
Had the issue again today and the problem was with expressions in debug mode. I was calling connect there, I guess while testing so in case anyone didn't know, expressions do affect your variables and can change what's in memory. For instance, having:
int a = 5;
System.out.println(a);
in your code and having a = 6 in your Expressions list, System.out.println(a) will print 6, not 5.
Deleting expressions fixed my problem.
I think your question already has an answer here.
Closing URLConnection and InputStream correctly?
Close your connection at end of the code and don't do it before setRequest method.

Why HttpURLConnection does not send data unless I try to receive something

I cannot comprehend why doesn't the following code does not put a packet onto wire (confirmed via wireshark). It is a fairly standard method of sending an HTTP POST request, as I believe. I don't intend to read anything just POST.
private void sendRequest() throws IOException {
String params = "param=value";
URL url = new URL(otherUrl.toString());
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setDoOutput(true);
con.setDoInput(true); //setting this to `false` does not help
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "text/plain");
con.setRequestProperty("Content-Length", "" + Integer.toString(params.getBytes().length));
con.setRequestProperty("Accept", "text/plain");
con.setUseCaches(false);
con.connect();
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(params);
wr.flush();
wr.close();
//Logger.getLogger("log").info("URL: "+url+", response: "+con.getResponseCode());
con.disconnect();
}
What happens is... actually nothing, unless I try to read anything. For example by uncommenting the above log line which reads the response code. Trying to read a response via con.getInputStream(); also works. There is no movement of packets. When I uncomment the getResponseCode, I can see that http POST is sent, and then 200 OK is sent back. The order is proper. I.e. I don't get some wild response before sending POST. Everything else looks exactly the same (I can attach wireshark screenshots if needed.). In the debugger the code executes (i.e. does not block anywhere).
I don't understand under what circumstances this can be happening. I belive it should be possible, to send a POST request with con.setDoInput(false);. Currently it doesn't send anything or fails (when trying to execute con.getResponseCode()) with an exception because I obviously promised I won't read anything.
It might be relevant, that before sendRequest I do request some data from the same site, but I trust I close everything properly. I.e:
public static String getData(String urlAddress) throws MalformedURLException, IOException {
URL url = new URL(urlAddress);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setDoOutput(false);
InputStream in = con.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder data = new StringBuilder();
String line;
while((line = reader.readLine()) != null) {
data.append(line);
}
reader.close();
in.close();
con.getResponseCode();
con.disconnect();
return data.toString();
}
The server for url in both cases is the same, port also, so I believe it is possible to use the same socket for communication. The above code works and retrieves the data properly.
I am not sure, maybe I don't clean something, and it gets cached, so with out an explicit read the POST gets delayed. There is no other traffic on the socket.
Unless you're using fixed-length or chunked transfer mode, HttpURLConnection will buffer all your output until you call getInputStream() or getResponseCode(), so that it can send a correct Content-length header.
If you call getResponseCode() you should have a look at its value.

HttpURLConnection getInputStream() has one second delay

I am using HttpURLConnection for making POST requests. I observe always the same behaviour during tests:
first request runs very fast (miliseconds)
all following requests take one second + some miliseconds
So something is causing 1 second delay. What can it be? The delay is happening exactly in HttpURLConnection#getInputStream().
I replaced the implementation with HttpClient - then everything is OK, no second delays (so it is not the server fault). But I really don't want to use any external dependency, so I would like to fix the HttpURLConnection thing... Any ideas?
Below current implementation. I tried some tips from stackoverflow (adding headers to the request), but with no success.
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Length", ""
+ (body == null ? 0 : body.length));
// Send post request
con.setDoOutput(true);
OutputStream wr = con.getOutputStream();
if (body != null) {
wr.write(body);
}
wr.flush();
wr.close();
BufferedReader rd = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String line;
String result = "";
while ((line = rd.readLine()) != null) {
result += line;
}
rd.close();
con.disconnect();
return result;
PS: It is about jse, not android.
You're never closing the input stream from the connection - that may mean that the connection isn't eligible for pooling, and on the next attempt it's waiting for up to a second to see if the previous request's connection will become eligible for pooling.
At the very least, it would be a good idea to close the stream. Use a try-with-resources block if you're using Java 7 - and ditto for the writer.
As an aside, I suggest you explicitly state the encoding you expect when reading - or use a higher-level library which detects that automatically based on headers.

Picasa getAlbum request not working Android

String album = "http://picasaweb.google.com/data/feed/api/user/"+email;
HttpURLConnection con = (HttpURLConnection) new URL(albumUrl).openConnection();
// request method, timeout and headers
con.setRequestMethod("GET") ;
con.setReadTimeout(15000);
con.setRequestProperty("Authorization", "GoogleLogin auth="+auth);
con.setRequestProperty("GData-Version", "2");
// set timeout and that we will process output
con.setReadTimeout(15000);
con.setDoOutput(true);
// connnect to url
con.connect();
// read output returned for url
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
Problem : Everytime i call con.getInputStream() it gives me file not found exception.
But when i load the same url in the desktop browser then it is displaying correct data.
I am confused why on android it is throwing exception.
Thanks in advance.
Did you get this? Maybe you just missed the https
below example uses default for authenticated user and the experimental fields list.
url = "https://picasaweb.google.com/data/feed/api/user/default?kind=album&access=public&fields="
+ URLEncoder
.encode("entry(title,id,gphoto:numphotosremaining,gphoto:numphotos,media:group/media:thumbnail)",
"UTF-8");
https://developers.google.com/picasa-web/docs/2.0/developers_guide_protocol#ListAlbums

Categories

Resources