Can't send JSON in a Java HTTP POST request - java

I'm getting a 'Server returned HTTP response code: 500' error although I have checked what I'm sending (I even tried sending it with an online tool and it worked). The API Key and the JSON are correct. I get this error when trying to read the input stream with 'connection.getInputStream()'. Where could this be comming frome ? Did I forget something ? I am trying to implement this feature from the openrouteservice API : https://openrouteservice.org/dev/#/api-docs/v2/directions/{profile}/post
public static UPSRoute getRoute(Location start, Location end, String language) {
if (language.equals("fr")) {
JSONObject jsonObject = null;
try {
URL url = new URL("https://api.openrouteservice.org/v2/directions/foot-walking");
String payload = "{\"coordinates\":[[" + start.getCoordinates() + "],[" + end.getCoordinates() + "]],\"language\":\"fr\"}";
System.out.println(payload); //{"coordinates":[[1.463478,43.562038],[1.471717,43.560787]],"language":"fr"}
byte[] postData = payload.getBytes(StandardCharsets.UTF_8);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", API_KEY);
connection.setRequestProperty("Accept", "application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8");
connection.setDoOutput(true);
try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
wr.write(postData);
}
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); // Error is right here
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
connection.disconnect();
jsonObject = new JSONObject(content.toString());
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return new UPSRoute(jsonObject);
} else {
return getRoute(start, end);
}
}
Here is the error :
java.io.IOException: Server returned HTTP response code: 500 for URL: https://api.openrouteservice.org/v2/directions/foot-walking/json
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1913)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:245)
at UPSRouteService.getRoute(UPSRouteService.java:63)
at Main.main(Main.java:5)

Thanks to Andreas, it was just missing the line :
connection.setRequestProperty("Content-Type", "application/json");
It works fine now.

Related

Android error: java.net.SocketException Socket is closed

I get java socket is closed exception meanwhile I am trying to read the response that I got from my web service. My web service sends a JSON as a response and the http code response is always 200 but I do not know if the response String is so long that BufferedReader crash when I try to use readLine(). If the issue is my response size, there is another way to get my json response?
I already used postman to be secured that my web service is working without problems, so I get my json responde as I want.
I use this same format of code to call other web services that I have and I do not have this issue. And actually, this code worked well before, since yesterday that I have this problem.
The error arises in the while below
try {
url = new URL(ws);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
//HEADERS
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("User-Agent", "Mozilla/5.0" + " (Linux; Android 1.5; es-ES) Ejemplo HTTP");
connection.connect();
OutputStream outputStream = connection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
bufferedWriter.write(jsonObject.toString());
bufferedWriter.flush();
bufferedWriter.close();
int response = connection.getResponseCode();
connection.disconnect();
StringBuilder result = new StringBuilder();
if (response == HttpURLConnection.HTTP_OK) {
InputStream input = new BufferedInputStream(connection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
if (!result.toString().equals("null")) {
JSONArray jsonResult = new JSONArray(result.toString());
if (jsonResult.length() > 0) {
//code to use JSON response info
} else {
//code to show alert dialog error
}
} else {
//code to show alert dialog error
}
} else {
//code to show alert dialog error
}
} catch (Exception e) {
Log.i("JSONWSResponse error: ", e.toString());
//code to show alert dialog error
}

Unable to read 404 error response body from azure

I am trying to read the response body for an error response(404,400,500) using java application and basic http client. When testing in my local , I am able to get the proper json response. But when I deployed to azure I am getting the error response body in HTML tags.
Error response I got when deployed to azure and testing from there:
400 Error400 error while attempting to access resource
#AddLoggerInAppInsights
public Map exchangeNativeHttpRequest(String url, String jsonPayLoad, String correlationId) {
Map<String,Object> responseMap = null;
try {
URL httpUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty(CLIENT_ID_KEY, System.getenv(CLIENT_ID_VALUE));
conn.setRequestProperty(CLIENT_SECRET_KEY, System.getenv(CLIENT_SECRET_VALUE));
conn.setRequestProperty(CORRELATION_ID, correlationId);
OutputStream os = conn.getOutputStream();
os.write(jsonPayLoad.getBytes());
os.flush();
HttpStatus httpStatus = HttpStatus.valueOf(conn.getResponseCode());
BufferedReader br = null;
if (conn.getResponseCode() == org.apache.http.HttpStatus.SC_OK) {
br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
}else if (conn.getResponseCode() == org.apache.http.HttpStatus.SC_BAD_REQUEST){
br = new BufferedReader(new InputStreamReader(
(conn.getErrorStream())));
}else {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
String output;
StringBuilder sb = new StringBuilder();
while ((output = br.readLine()) != null) {
sb.append(output);
}
telemetryClient.trackEvent(correlationId+":" +"Response for Create Breakdown IBMI API from HTTP_CONNECTION: "+sb.toString());
responseMap = new HashMap<>();
responseMap.put("statusCode",httpStatus);
responseMap.put("response", sb.toString());
conn.disconnect();
} catch (MalformedURLException e) {
telemetryClient.trackException(e);
} catch (IOException e) {
telemetryClient.trackException(e);
}
telemetryClient.trackEvent(correlationId+":" +"Returned Response of Create Breakdown IBMI API from HTTP_CLIENT: "+responseMap.toString());
return responseMap;
}

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.

HttpURLConnection always failing with 401

I'm trying to use HttpURLConnection for connecting to server from Android app which I'm developing. For now, I'm testing the connection code not in an app but as a plain java program with main class. I guess this doesn't make any difference as far as HttpUrlConnection.
Please examine the code snippet. Another issue is even errorStream is throwing null. This I feel is because of malformed URL.
private static String urlConnectionTry() {
URL url; HttpURLConnection connection = null;
try {
String urlParameters = "email=" + URLEncoder.encode("email", "UTF-8") +
"&pwd=" + URLEncoder.encode("password", "UTF-8");
//Create connection
url = new URL("http://example.com/login");
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("uuid", getUuid());
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(true);
//Send request
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes (urlParameters);
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getErrorStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
private static String getUuid() {
try {
Document doc=Jsoup.connect("http://example.com/getUuid").get();
Elements metaElems = doc.select("meta");
for (Element metaElem : metaElems) {
if(metaElem.attr("name").equals("uuid")) {
return metaElem.attr("content");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
You're probably receiving 401 because the credentials that was sent to the server is not authorized- it's probably not registered or the password is incorrect.
As for the null error stream, take a look at this SO answer.
If the connection was not connected, or if the server did not have an error while connecting or if the server had an error but no error data was sent, this method will return null.
It is probably better if you check first the response code using HttpUrlConnection#getResponseCode(). Decide on whether you'll be checking the contents of the error stream based on the response code you get.

Querying Data from SUGARCRM

I have SugarCRM trail account. I can able to get Authenticate and get the AccessToken by the following url.
https://xxxxxxx.trial.sugarcrm.eu/rest/v10/oauth2/token
Method : POST
POST Data : postData: { "grant_type":"password", "client_id":"sugar", "client_secret":"", "username":"admin", "password":"Admin123", "platform":"base" }
Code I used to get the AccessToken
public static String getAccessToken() throws JSONException {
HttpURLConnection connection = null;
JSONObject requestBody = new JSONObject();
requestBody.put("grant_type", "password");
requestBody.put("client_id", CLIENT_ID);
requestBody.put("client_secret", CLIENT_SECRET);
requestBody.put("username", USERNAME);
requestBody.put("password", PASSWORD);
requestBody.put("platform", "base");
try {
URL url = new URL(HOST_URL + AUTH_URL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.connect();
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
out.write(requestBody.toString());
out.close();
int responseCode = connection.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
JSONObject jObject = new JSONObject(response.toString());
if(!jObject.has("access_token")){
return null;
}
String accessToken = jObject.getString("access_token");
return accessToken;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Now I have retrive Leads from CRM using rest API I can not able to find the appropriate method and Url to do the thing.
I can see the list rest of API's from /help but I cant understand what should be my module name and what I have to :record and how do I pass my access token for authentication.
Can anyone please help me?
The module name is simply the module you which to fetch records from, so in your case you'll want to do a GET request to rest/v10/Leads for a list of Leads. If you want to fetch a specific Lead you replace :record with the id of a Lead - for example: GET rest/v10/Leads/LEAD-ID-HERE
SugarCRM's documentation has a lot of relevant information that might not be included in /help plus working examples.
http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_7.8/Integration/Web_Services/v10/Endpoints/module_GET/
http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_7.8/Integration/Web_Services/v10/Examples/PHP/How_to_Fetch_Related_Records/
You need to include your retrieved token into an OAuth-Token header for subsequent requests, and then just use the module name as the endpoint i.e. in your case: "rest/v10/Leads" and call the GET method to retrieve them. Try something akin to this:
String token = getAccessToken();
HttpURLConnection connection = null;
try {
URL url = new URL(HOST_URL + "/rest/v10/Leads");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("OAuth-Token", token);
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.connect();
int responseCode = connection.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
JSONObject jObject = new JSONObject(response.toString());
System.out.println(jObject);
} catch (Exception e) {
e.printStackTrace();
}
In the case you want to filter it down to specific id's to cut down on the amount of returned data, you can specify it after the module name i.e. "rest/v10/Leads/{Id}"

Categories

Resources