HttpURLConnection fails with 404 Error - java

My httpURLConnection fails with 404 - Resource not Found error. The same URL works on my firefox poster and returns 200/ok. Both the applications(webapp and the URL-app) are located on the same machine. I found from another thread that I need to add below 2 lines to make it work when the same URL works from browser-
urlConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
urlConnection.setRequestProperty("Accept","/");
Unfortunately adding above lines didn't fix the problem. Am I doing anything wrong in the code below ? Any useful suggestions will be much appreciated.
{
String computerName = InetAddress.getLocalHost().getHostName();
url = new URL("http://"+computerName+":8080"+"/cerprovider/devices");
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDefaultUseCaches(false);
urlConnection.setUseCaches(false);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Content-Length", Integer.toString(Integer.MAX_VALUE));
urlConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
urlConnection.setRequestProperty("Accept","*/*");
urlConnection.setConnectTimeout(500);
// Create I/O streams
outStream = new DataOutputStream(urlConnection.getOutputStream());
//inStream = new DataInputStream(urlConnection.getInputStream());
// Send request
outStream.writeBytes(<blah>.toString());
outStream.flush();
outStream.close();
BufferedReader in = null;
String responseErrorString = "";
_tracer.info("Response code --"+urlConnection.getResponseCode());
InputStream error = urlConnection.getErrorStream();
_tracer.info("Error from the connection --"+error.toString());
StringBuilder buf = new StringBuilder();
for(int c = -1; (c = error.read()) != -1; )
buf.append((char)c);
responseErrorString = new String (buf);
_tracer.info("responseErrorString--"+responseErrorString);
}

try to send request again. In my project I am using Apache HttpClient to send request & many times the 404 error resolve by sending request again. (but not all the time)
Also use httpfox plugin on firefox to check what exactly happening when u send request.
404 error is supposed to b for 'resource temporarily not available'.

Related

API works with token when called in chrome, but does not work with the same token when called from my code

I am trying to make an API call to get data from Navitia.
The URL looks like this :
https://{myToken}#api.navitia.io/v1/journeys?from={...}
When I copy paste the complete URL in a private tab browser it works fine, but when I call the API from my code I get a 401 error.
This is the code to call the API :
String sURL = "https://{myToken}#api.navitia.io/v1/journeys?from=" +longDeparture +";" + latDeparture + "&to="+ longArrival+ ";"+latArrival +"&";
URL url = new URL(sURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode != 200) {
throw new RuntimeException("HttpResponseCode: " + responseCode);
} else {...}
But it works here when copy pasting :
enter image description here
Finally, I stopped calling the API from the Java code.
What I do know is I create a process to curl the api from the terminal and I just fetch the output. I guess it's not the best solution but it works fine now.

Connection reset after getOutputStream invocation

I am to ask your kind help for a problem I cannot solve...
I have the following code:
String https_url = "https://...";
try {
HttpsURLConnection connection = (HttpsURLConnection) new URL(https_url).openConnection();
String query = "api_key=1234&portal_id=1234&username="+username;
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Length", String.valueOf(query.length()));
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
output.writeBytes(query);
output.close();
DataInputStream input = new DataInputStream( connection.getInputStream() );
String ret = "";
for( int c = input.read(); c != -1; c = input.read() ) {
ret += (char)c ;
}
input.close();
int code = connection .getResponseCode();
String message = connection .getResponseMessage();
System.out.println("Resp Code:"+code);
System.out.println("Resp Message:"+ message);
//...
This code has been running for a couple of years, and until some weeks ago, it has worked fine, then suddenly, it started to got a
java.net.SocketException: Connection reset
soon after the line
output = new DataOutputStream(connection.getOutputStream());
This code runs into a Java web application, and it is called after the click on a button of a web page.
I don't know if something has changed on server side, but the strange thing is that if I put this code into a main method of a stand alone class, export the class on an executable jar file, and launch the jar from the same environment where the web application is deployed, this code still works and I don't get any exception.
Any suggestions? Thank you again
Step

HttpURLConnection always return error 500

i'm trying to run a soap request in a basic http request...naturally i tried with external tools the message and is correct, like the endpoint i'm using as targetUrl, the wsdl is in something like
http://00.00.00.00/a-ws/services/basic?wsdl
and my actual end point is
http://00.00.00.00/a-ws/services/basic.targetservice
and i'm using this last as target url
URL url = new URL(targetUrl);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
connection.setRequestProperty("SOAPAction", action);
connection.setRequestProperty("User-Agent", "myagent");
connection.setRequestProperty("Host", "localhost");
//connection.setRequestProperty("Content-Length", "" + Integer.toString(message.getBytes().length));
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
OutputStream wr = connection.getOutputStream ();
wr.write (message.getBytes());
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line=null;
StringBuffer response = new StringBuffer();
while( (line = rd.readLine()) != null) {
if (line!=null)
response.append(line);
}
rd.close();
return response.toString();
the raw message is tested with chrome plugin, the only thing i can't test is headers but the result is always an exception on getInputStream
java.io.IOException: Server returned HTTP response code: 500 for URL:
why?
It was a very stupid issue of encoding (like I was supposing)...i didn't escape double quote inside the message.
The evidence of problem was visible using a fake http server that just echo contents.
UPDATE:
Another thing nobody already pointed out is that is useful in case of exception to retrieve
connection.getErrorStream()
that contains the response in case of error!

HTTP Get on Android Emulator

Today I started developing a new Android app which is based on the Windows Azure Mobile Services.
I've tried to use the SDK provided by Microsoft for the whole day, without any success. Every time the app performs a web request, this one returns a 400, BAD REQUEST code.
I go to a lower level, with the following code.
URL url = new URL("https://xxxx.azure-mobile.net/api/contents"); //host obscured
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
//I obscure the authentication and app key, but they are correct in the program
conn.addRequestProperty("AUTHORIZATION", "Basic xxxxxxxxxxxxxxx");
conn.addRequestProperty("X-ZUMO-APPLICATION", "xxxxxxxxxxxxxxxx");
conn.addRequestProperty("ACCEPT", "application/json");
//connect
conn.connect();
int code = conn.getResponseCode(); //400 in the emulator, 200 in a standard java code
String message = conn.getResponseMessage();
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String read = null;
StringBuilder sb = new StringBuilder();
do {
//Read the content
read = br.readLine();
sb.append(read);
} while(read != null);
//print the content
System.out.println(sb.toString());
//Close the buffers
br.close();
isr.close();
is.close();
System.out.println("Status Code: "+code);
System.out.println(message);
conn.disconnect();
It works perfectly in a standard java application, but in the emulator I still get 400 BAD REQUEST. I really do not understand why!
Maybe an issue of the emulator?
I was running an Android Emulator with API 10.
I'd like to try the code on a real device, but the mac does not recognize it... And the device worked until yesterday since I debugged an application with it.
If you know what I am doing wrong, please help me.
EDIT 20-03-2014:
I made some other attempts. I tried with the HttpClient API. No luck.
I'm still getting 400 as response code and Bad Request as response Message.
The thrown Exception is UnknownHostException... But the InetAddress.getByName(); successfully get an IP address for my web service.
The app still work with Android version greater than 4, I have not tried with Android 3.
I'm very sad and frustrated...
Thank you for your time,
Rik.
SOLVED
Oddly, the problem was in the AUTHENTICATION header.
I computed the header with the following code:
public setHeader(String code, String username)
{
StringBuilder sb = new StringBuilder(username);
sb.append(":");
sb.append(code);
sb = new StringBuilder(Base64.encodeToString(sb.toString().getBytes(), Base64.DEFAULT));
sb.insert(0, "Basic ");
auth = sb.toString();
}
The Base64.encodeToString() method adds a \n at the end of the line. .__.
By adding a trim() in the last line, I threw away the new line and everything went fine in both 2.3.3 and 4 Android versions.

Java HTTPUrlConnection returns 500 status code

I'm trying to GET a url using HTTPUrlConnection, however I'm always getting a 500 code, but when I try to access that same url from the browser or using curl, it works fine!
This is the code
try{
URL url = new URL("theurl");
HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();
httpcon.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httpcon.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:14.0) Gecko/20100101 Firefox/14.0.1");
System.out.println(httpcon.getHeaderFields());
}catch (Exception e) {
System.out.println("exception "+e);
}
When I print the headerfields, it shows the 500 code.. when I change the URL to something else like google.com , it works fine. But I don't understand why it doesn't work here but it works fine on the browser and with curl.
Any help would be highly appreciated..
Thank you,
This is mostly happening because of encoding.
If you are using browser OK, but getting 500 ( internal server error ) in your program,it is because the browsers have a highly sophisticated code regarding charsets and content-types.
Here is my code and it works in the case of ISO8859_1 as charset and english language.
public void sendPost(String Url, String params) throws Exception {
String url=Url;
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setRequestProperty("Acceptcharset", "en-us");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setRequestProperty("charset", "EN-US");
con.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
String urlParameters=params;
// Send post request
con.setDoOutput(true);
con.setDoInput(true);
con.connect();
//con.
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
this.response=response.toString();
con.disconnect();
}
and in the main program , call it like this:
myclassname.sendPost("https://change.this2webaddress.desphilboy.com/websitealias/orwebpath/someaction","paramname="+URLEncoder.encode(urlparam,"ISO8859_1"))
The status code 500 suggests that the code at web server have been crashed .Use HttpURLConnection#getErrorStream() to get more idea of the error. Refer Http Status Code 500
I ran into the problem of "URL works in browser, but when I do http-get in java I get a 500 Error".
In my case the problem was that the regular http-get ended up in an infinite redirect loop between /default.aspx and /login.aspx
URL oUrl = new URL(url);
HttpURLConnection con = (HttpURLConnection) oUrl.openConnection();
con.setRequestMethod("GET");
...
int responseCode = con.getResponseCode();
What was happening was: The server serves up a three-part cookie and con.getResponseCode() only used one of the parts. The cookie data in the header looked like this:
header.key = null
value = HTTP/1.1 302 Found
...
header.key = Location
value = /default.aspx
header.key = Set-Cookie
value = WebCom-lbal=qxmgueUmKZvx8zjxPftC/bHT/g/rUrJXyOoX3YKnYJxEHwILnR13ojZmkkocFI7ZzU0aX9pVtJ93yNg=; path=/
value = USE_RESPONSIVE_GUI=1; expires=Wed, 17-Apr-2115 18:22:11 GMT; path=/
value = ASP.NET_SessionId=bf0bxkfawdwfr10ipmvviq3d; path=/; HttpOnly
...
So the server when receiving only a third of the needed data got confused: You're logged in! No wait, you have to login. No, you're logged in, ...
To work around the infinite redirect-loop I had to manually look for re-directs and manually parse through the header for "Set-cookie" entries.
con = (HttpURLConnection) oUrl.openConnection();
con.setRequestMethod("GET");
...
log.debug("Disable auto-redirect. We have to look at each redirect manually");
con.setInstanceFollowRedirects(false);
....
int responseCode = con.getResponseCode();
With this code the parsing of the cookie, if we get a redirect in the responseCode:
private String getNewCookiesIfAny(String origCookies, HttpURLConnection con) {
String result = null;
String key;
Set<Map.Entry<String, List<String>>> allHeaders = con.getHeaderFields().entrySet();
for (Map.Entry<String, List<String>> header : allHeaders) {
key = header.getKey();
if (key != null && key.equalsIgnoreCase(HttpHeaders.SET_COOKIE)) {
// get the cookie if need, for login
List<String> values = header.getValue();
for (String value : values) {
if (result == null || result.isEmpty()) {
result = value;
} else {
result = result + "; " + value;
}
}
}
}
if (result == null) {
log.debug("Reuse the original cookie");
result = origCookies;
}
return result;
}
Make sure that your connection allows following redirects - this is one of the possible reasons for difference in behaviour between your connection and the browser (allows redirect by default).
It should be returning code 3xx, but there maybe something else somewhere that changes it to 500 for your connection.
I faced the same issue, and our issue was there was a special symbol in one of the parameter values. We fixed it by using URLEncoder.encode(String, String)
In my case it turned out that the server always returns HTTP/1.1 500 (in Browser as in Java) for the page I wanted to access, but successfully delivers the webpage content nonetheless.
A human accessing the specific page via Browser just doesn't notice, since he will see the page and no error message, in Java I had to read the error stream instead of the input stream (thanks #Muse).
I have no idea why, though. Might be some obscure way to keep Crawlers out.
This is an old question, but I have had same issue and solved it this way.
This might help other is same situation.
In my case I was developing system on local environment, and every thing worked fine when I checked my Rest Api from browser but I got all the time thrown HTTP error 500 in my Android system.
The problem is when you work on Android, it works on VM (Virtual Machine), that said it means your local computer firewall might preventing your Virtual Machine accessing the local URL (IP) address.
You need just to allow that in your computer firewall. The same thing apply if you trying to access system from out side your network.
Check the parameter
httpURLConnection.setDoOutput(false);
Only for GET Method and set to true on POST, this save me lot of time!!!

Categories