Https Request working with curl but failing with HttpsURLConnection - java

I have a curl request which looks like below:-
curl -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d '{"Request": {"Orders":[{"id_sales_order": 160407400833822,"address_billing": {"first_name":"John","last_name": "Doe","phone": "1234567","phone2": "1234","address1": "Sesamestreet 123","city": "Berlin","postcode": "12345","country": "Germany"}}]}}' "https://debraj:debrajmanna#example.com/oms-api/?Action=UpdateOrderInformation&ServiceName=OMS&Signature=e436d6c7c930fa37a30a8b67051cb4531dad92b0c904a5a009bb4529a762dcd7&Timestamp=2016-04-09T19%3A14%3A12%2B0530&Version=1.0"
This is giving output:-
{"ErrorResponse":{"Head":{"RequestAction":"UpdateOrderInformation","ErrorType":"Sender","ErrorCode":0,"ErrorMessage":"Some elements were not processed"},"Body":{"UpdateOrderInformation":[{"ErrorCode":null,"ErrorMessage":"Order with source id: 160407400833822 was not found","Position":0}]}}}
To implement this in Java I have the below java code. But the java code is not behaving as expected. Can some let me know what I am doing wrong?
public class CurlMain {
public static void main(String[] args) throws Exception {
String url = "https://example.com/oms-api/";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setRequestMethod("POST");
String authStr = String.format("%s:%s", "debraj", "debrajmanna");
String body = "{'Request': {'Orders':[{'id_sales_order': 160407400833822,'address_billing': {'first_name':'John','last_name': 'Doe','phone': '1234567','phone2': '1234','address1': 'Sesamestreet 123','city': 'Berlin','postcode': '12345','country': 'Germany'}}]}}";
String encodedAuthStr = Base64.getEncoder().encodeToString(authStr.getBytes(StandardCharsets.UTF_8));
con.setRequestProperty("Authorization", "Basic " + encodedAuthStr);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
String urlParameters = "Action=UpdateOrderInformation&ServiceName=OMS&Signature=e436d6c7c930fa37a30a8b67051cb4531dad92b0c904a5a009bb4529a762dcd7&Timestamp=2016-04-09T19%3A14%3A12%2B0530&Version=1.0";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.writeBytes(body);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
HttpsURLConnection.setFollowRedirects(true);
Map<String, List<String>> headers = con.getHeaderFields();
System.out.println(headers.toString());
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println("Curl Response " + response.toString());
}
whereas the java code is printing:-
{"ErrorResponse":{"Head":{"RequestAction":"","ErrorType":"Sender","ErrorCode":"9","ErrorMessage":"E009: Access Denied"},"Body":""}}
I don't have access to the server code or server configuration. My goal is to send the same curl request through the java code and get the same response.
I am using java 8.
Am I missing anything?

Appending the query parameters to the url solved the issue like below:-
URL obj = new URL(new StringBuilder(url).append("?").append(urlParameters).toString());
...
//wr.writeBytes(urlParameters);

Related

How to use http request method: "LIST"

I have a curl with "LIST" as request type. I try to translate this curl in a Rest API using RestTemplate, but I can't set the HttpMethod because there isn't a LIST method. I also tried to use HttpURLConnection, but I receive 404 Error because it does not recognize LIST as a valid method.
this is the curl:
curl --header "Token: <token_value>" -k --request LIST https://example_path/application/metadata/
(the "/" at the end of URL isn't an error: it is necessary for this type of request)
this is the java code trying to use restTemplate (obviously HttpMethod.LIST returns me error):
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.set("Token", token);
HttpEntity<String> entity = new HttpEntity<String>(headers);
String url = "https://example_path/application/metadata/";
ResponseEntity<String> res = restTemplate.exchange(url, HttpMethod.LIST, entity, String.class);
this is the java code using HttpURLConnection:
URL url = new URL("https://example_path/application/metadata/");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("LIST");
con.setRequestProperty("Token", token);
int responseCode = con.getResponseCode();
System.out.println("Response code: " + responseCode);
InputStreamReader inputStreamReader = null;
if (responseCode >= 200 && responseCode < 400) {
inputStreamReader = new InputStreamReader(con.getInputStream());
} else {
inputStreamReader = new InputStreamReader(con.getErrorStream());
}
BufferedReader in = new BufferedReader(inputStreamReader);
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
return response.toString();
}
I also tried to use con.setRequestProperty("X-HTTP-Method-Override", "LIST") in HttpURLConnection.

Java HTTP Request with Token Authentication

I am trying to make a GET request to a local server I have running. I am having trouble returning the correct data, I am seeing an 'Unauthorized' response. Can anyone spot any glaring issues with this given that the String 'token' is correct.
protected Object doInBackground(Void... params) {
try {
String url = "http://192.168.0.59:8000/events/";
URL object = new URL(url);
HttpURLConnection con = (HttpURLConnection) object.openConnection();
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestMethod("GET");
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Authorization:", "Token " + token);
//Display what the GET request returns
StringBuilder sb = new StringBuilder();
int HttpResult = con.getResponseCode();
if (HttpResult == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(
new InputStreamReader(con.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
} else {
System.out.println(con.getResponseMessage());
}
} catch (Exception e) {
Log.d("Uh Oh","Check your network.");
return false;
}
return false;
}*
I was able to get a curl request working from the command line:
curl -H "Authorization: Token token" http://0.0.0.0:8000/events/
try this
con.setRequestProperty("Authorization", "Bearer " + token);
It turns out this issue was caused by including the con.setDoOutput(true); as get requests do not include a body.

HttpsURLConnection - Send POST request

I want to send a POST request to this particular API: https://developer.lufthansa.com/docs/read/api_basics/Getting_Started and I researched how to do that and tried everything but it simply doesn't work, I always get an HTTP 400 or an HTTP 401 error. Here's my code:
private void setAccessToken(String clientID, String clientSecret) {
try {
URL url = new URL(URL_BASE + "oauth/token");
String params = "client_id=" + clientID + "&client_secret=" + clientSecret + "&grant_type=client_credentials";
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream());
osw.write(params);
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch(IOException e) {
e.printStackTrace();
}
}
Kenta1561
Seems that your code is working well and it may be the case that you are providing invalid clientID or clientSecret so that your are getting wrong response in this case (as 401 indicates unauthorized). One thing you can do is you are only getting the response message if the http request status is ok (200). You may also get the invalid response message in case of 400 or 401 http response status. In order to print the invalid response messages you may follow the code below:
private void setAccessToken(String clientID, String clientSecret) throws Exception {
String params = "client_id=" + clientID + "&client_secret=" + clientSecret + "&grant_type=client_credentials";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
BufferedReader in;
// add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(params);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
if (responseCode >= 400)
in = new BufferedReader(new InputStreamReader(con.getErrorStream()));
else
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
}
In this way you can also get invalid response message. In your case when I tried to hit the provided api it is giving me the response below:
{"error": "invalid_client"}

What is the Java equivalent to use https://fcm.googleapis.com/fcm/send REST Api

I've already tried the following command in Curl to send a notification using the Firebase REST Api and it works:
curl -X POST --header "Authorization: key=AIza...iD9wk" --Header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d "{\"notification\":{\"title\": \"My title\", \"text\": \"My text\", \"sound\": \"default\"}, \"to\": \"cAhmJfN...bNau9z\"}"
Now that I'm trying to do the same in Java, I couldn't find an easy way to do the same and nothing that I've tried triggers the notification in my mobile endpoint.
This is my closest approach:
try {
HttpURLConnection httpcon = (HttpURLConnection) ((new URL("https://fcm.googleapis.com/fcm/send").openConnection()));
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Authorization: key", "AIza...iD9wk");
httpcon.setRequestMethod("POST");
httpcon.connect();
System.out.println("Connected!");
byte[] outputBytes = "{\"notification\":{\"title\": \"My title\", \"text\": \"My text\", \"sound\": \"default\"}, \"to\": \"cAhmJfN...bNau9z\"}".getBytes("UTF-8");
OutputStream os = httpcon.getOutputStream();
os.write(outputBytes);
os.close();
// Reading response
InputStream input = httpcon.getInputStream();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input))) {
for (String line; (line = reader.readLine()) != null;) {
System.out.println(line);
}
}
System.out.println("Http POST request sent!");
} catch (IOException e) {
e.printStackTrace();
}
But then I get:
java.io.IOException: Server returned HTTP response code: 401 for URL: https://fcm.googleapis.com/fcm/send
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at httpclient.test.MyHttpClientPost.sendNotification(MyHttpClientPost.java:131)
at httpclient.test.MyHttpClientPost.main(MyHttpClientPost.java:26)
401 means unauthorized, so no valid Authorization header was sent.
And this line:
httpcon.setRequestProperty("Authorization: key", "AIza...iD9wk");
Is not equivalent to -H "Authorization: key=AIza...iD9wk". The first argument should be the header name, which is Authorization:
httpcon.setRequestProperty("Authorization", "key=AIza...iD9wk");
In conclusion, you misunderstood how HTTP header is formatted. Basically the header name and value are separated by : not =.
Minimal sample:
public class ConnApp {
public static void main(String[] args) throws Exception {
HttpURLConnection httpcon = (HttpURLConnection) ((new URL("https://fcm.googleapis.com/fcm/send").openConnection()));
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Authorization", "key=!!secret!!");
httpcon.setRequestMethod("POST");
httpcon.connect();
byte[] outputBytes = ("{\"to\":\"!!CONFIDENTIAL!!\"," +
"\"data\":{\"some\":\"thing\"}," +
"\"notification\":{\"title\":\"Help\",\"body\":\"me\",\"icon\":\"me\",\"sound\":\"default\",\"badge\":\"18\"}," +
"\"priority\":\"high\"," +
"\"content_available\":true}").getBytes("UTF-8");
OutputStream os = httpcon.getOutputStream();
os.write(outputBytes);
os.close();
InputStream input = httpcon.getInputStream();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input))) {
for (String line; (line = reader.readLine()) != null;) {
System.out.println(line);
}
}
}
}

HTTP Request through java getting 401 response

I am trying to invoke a url through java using java.net.HttpURLConnection.
Below is the code.
I get 401 as response. The url is up.
// HTTP GET request
private void sendGet() throws Exception {
String url = "http://10.10.200.151:8720/scheduler/stat.go?opt1=0&opt2=0&opt3=0";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
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());
}
Is there something missing.
HTTP status 401 indicate that the request requires authentication.
Perhaps this url need login, and the server check this by your cookie.

Categories

Resources