I'm creating an application that needs to get an answer from a webservice that response as json object. I've already test URL on browser and it works very well but using Java(J2SE) it doesn't works and throws an exception 451 from server.
I don't know why it works on browser and doesn't works on j2se and how to fix it.
How could I fix this ?
The URL: https://economia.awesomeapi.com.br/all/USD-BRL
Exception
Server returned HTTP response code: 451 for URL: https://economia.awesomeapi.com.br/all/USD-BRL
Method
public void getJsonFromURL(){
try{
URL u = new URL("https://economia.awesomeapi.com.br/all/USD-BRL");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
c.setRequestProperty("Accept", "application/json");
c.setRequestProperty("access-control-allow-origin", "*");
c.setRequestProperty("server", "keycdn-engine");
c.setRequestMethod("GET");
c.setDoOutput(true);
c.setDoInput(true);
c.connect();
int status = c.getResponseCode();
System.out.println("Code Response: " + status);
//Exception
Server returned HTTP response code: 451 for URL: https://economia.awesomeapi.com.br/all/USD-BRL
}catch(Exception e){
System.out.println("Erro: " + e.getLocalizedMessage());
}
}
Seems I found it, the server doesn't like if the user-agent header isn't there. The request below gave me a result. Even if the parameter has no value, its accepted.
I couldn't be some certificate/ssl/tls issue since the connection was established and the server actually replied, it just didn't like the request very much. This line did it:
con.setRequestProperty("User-Agent", "");
Related
I want to get the Content Length of this file by java:
https://www.subf2m.co/subtitles/farsi_persian-text/SImp4fRrRnBK6j-u2RiPdXSsHSuGVCDLz4XZQLh05FnYmw92n7DZP6KqbHhwp6gfvrxazMManmskHql6va6XEfasUDxGevFRmkWJLjCzsCK50w1lwNajPoMGPTy9ebCC0&name=Q2FwdGFpbiBNYXJ2ZWwgRmFyc2lQZXJzaWFuIGhlYXJpbmcgaW1wYWlyZWQgc3VidGl0bGUgLSBTdWJmMm0gW3N1YmYybS5jb10uemlw
When I insert this url in Firefox or Google Chrome, it downloads a file. but when i want to see that file's size by Java HttpsURlConnection, server returns me Response Code 403 and Content Length -1. why this happens? Thanks
try {
System.out.println("program started -----------------------------------------");
String str_url = "https://www.subf2m.co/subtitles/farsi_persian-text/SImp4fRrRnBK6j-u2RiPdXSsHSuGVCDLz4XZQLh05FnYmw92n7DZP6KqbHhwp6gfvrxazMManmskHql6va6XEfasUDxGevFRmkWJLjCzsCK50w1lwNajPoMGPTy9ebCC0&name=Q2FwdGFpbiBNYXJ2ZWwgRmFyc2lQZXJzaWFuIGhlYXJpbmcgaW1wYWlyZWQgc3VidGl0bGUgLSBTdWJmMm0gW3N1YmYybS5jb10uemlw";
URL url = new URL(str_url);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setConnectTimeout(150000);
con.setReadTimeout(150000);
con.setRequestMethod("HEAD");
con.setInstanceFollowRedirects(false);
con.setRequestProperty("Accept-Encoding", "identity");
con.setRequestProperty("connection", "close");
con.connect();
System.out.println("responseCode: " + con.getResponseCode());
System.out.println("contentLength: " + con.getContentLength());
} catch (IOException e) {
System.out.println("error | " + e.toString());
e.printStackTrace();
}
output:
program started -----------------------------------------
responseCode: 403
contentLength: -1
The default Java user-agent is blocked by some online services (most notably, Cloudflare). You need to set the User-Agent header to something else.
con.setRequestProperty("User-Agent", "My-User-Agent");
In my experience, it doesn't matter what you set it to, as long as it's not the default one:
con.setRequestProperty("User-Agent", "aaa"); // works perfectly fine
EDIT: looks like this site uses Cloudflare with DDoS protection active - your code won't run the JavaScript challenge needed to actually get the content of the file.
I want to call this curl command to get list of applicant names from Java in JSON
curl -u uname:pass my_REST_Endpoint_provided_by_vendor
here is my code:
URL myURL = new URL("url");
HttpURLConnection conn = (HttpURLConnection) myURL.openConnection();
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.setRequestMethod("PUT");
String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(unamepass.getBytes("UTF-8"));
conn.setRequestProperty ("Authorization", basicAuth);
int code = conn.getResponseCode(); // 200 = HTTP_OK
System.out.println("Response (Code):" + code);
System.out.println("Response (Message):" + conn.getResponseMessage());
If I run this command on my command prompt it runs fine and gives me the output but if I run this code I get Response (Code):405
java.io.IOException: Server returned HTTP response code: 405 for URL:
Where am I going wrong?
You are getting an 405 error because you are using the HTTP Method PUT instead of GET, which is used by curl by default. Remove the line:
conn.setRequestMethod("PUT");
Below is my code which does POST request to login to a website. When i run the same I receive Message response as 411. Can anybody help me to set the correct Content Length?
try {
String request = "http://<domain.com>/login";
URL url = new URL(request);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestProperty("Content-Length", "1");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("email", "abc");
connection.setRequestProperty("password", "xyz");
connection.setDoOutput(true);
connection.setRequestMethod("POST");
int code = connection.getResponseCode();
System.out.println("Response Code of the object is " +code);
if(code == 200)
System.out.println("OK");
connection.disconnect();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Ok - you're not moving anything into the body of the request so you should set the length to "0".
Add:
connection.connect();
after:
connection.setRequestMethod("POST");
google "httpurlconnection post parameters" for adding parameters to a POST request. This site has at least four or five solutions.
Although the answer might be too late, but just for future reference.
I faced exactly the same problem and for the reasons already mentioned I kept getting the same error.
I managed to work around the problem by sending just an empty body:
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = "".getBytes("utf-8");
os.write(input, 0, input.length);
}
That fixed the issue for me. Manually setting the Content-Length header does not help as already mentioned.
I was facing the same problem. I was trying to send a POST request with an empty body, but the request was rejected by the server, returning 411.
Then I found the following code in 'sun.net.www.protocol.http.HttpURLConnection', which is the implementation of 'java.net.HttpURLConnection':
private static final String[] restrictedHeaders = new String[]{"Access-Control-Request-Headers", "Access-Control-Request-Method", "Connection", "Content-Length", "Content-Transfer-Encoding", "Host", "Keep-Alive", "Origin", "Trailer", "Transfer-Encoding", "Upgrade", "Via"};
So, when you set a header via sun.net.www.protocol.http.HttpURLConnection.setRequestProperty, if the key is included in the array above, it will be ignored. That's why setting 'Content-Length' manually is not working.
I have a question about making a POST request with Java, and since this is my first attempt at something of this magnitude, please bear with me. I am working on a third party application in Java to connect to a website and make POST requests. Am I doing this correctly? Here is what I have so far:
Website Code:
(This is the code the website has for "bumping a trade" which simply sends 2 pieces of data to a php file. The URL is http://cdn.dota2lounge.com/script/trades.js)
function bumpTrade(trade, code) {
$.ajax({
type: "POST",
url: "ajax/bumpTrade.php",
data: "trade=" + trade + "&code=" + code
});
}
My Java Code:
private void sendPost() throws Exception {
//String url = "https://www.cdn.dota2lounge.com/script/ajax/bumpTrade.php";
String url = "https://www.cdn.dota2lounge.com/script/ajax/bumpTrade.php";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add request header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
String urlParameters = "trade=96510389&code=94cebd9";
// Send post request
con.setDoOutput(true);
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());
}
However I am receiving a connection timeout error when attempting to connect. I would be very grateful if someone could point me in the right direction!
The Java client code seems to be on the right track. But it looks like the URL in the code was the wrong URL.
Using the url "http://www.dota2lounge.com/ajax/bumpTrade.php" and HttpUrlConnection, I was able to get a 200 response (OK):
Sending 'POST' request to URL : http://www.dota2lounge.com/ajax/bumpTrade.php
Post parameters : trade=96510389&code=94cebd9
Response Code : 200
However nothing beyond that. Not sure of the API of the remote site but hopefully that's some help.
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!!!