Java HTTPURLConnection - Reading error response from code 400 with payload - java

I am trying to call an API that gives 400 on some requests.
But it has meaningful message that needs to be read.
Also i am passing a payload(json body) in the api call
My code(it takes a payload as json) and the 400 response is below
I am able to successfully read the response of 200 but issue is with 400
public static void blahblah (String input, String CustomerID, String endpoint, String dateNameFolder) throws UnknownHostException
{
try {
URL url = new URL(endpoint);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
StringBuilder sb = new StringBuilder();
String output;
while ((output = br.readLine()) != null) {
sb.append(output);
}
File fileObj = new File(CustomerID + ".json");
if (!fileObj.exists()) {
fileObj.createNewFile();
FileWriter dataWriter = new FileWriter(CustomerID + ".json");
dataWriter.write(sb.toString());
dataWriter.close();
} else {
FileWriter dataWriter = new FileWriter(CustomerID + ".json");
dataWriter.write(sb.toString());
dataWriter.close();
}
conn.disconnect();
}catch (MalformedURLException e) {
l
log.info(e);
}
catch (IOException e) {
log.error("Error in Validating Request to Catalog for Customer ID(400 Bad Request) : " + CustomerID ) ;
log.info(e);
}
}
Sample output of 400 bad request :
<Response>
<StatusCode>BadRequest</StatusCode>
<ErrorCode>OrderRequestInvalid.InvalidCharacteristicUse</ErrorCode>
<Message>Characteristic ID cannot be found in the specification: { EntityUniqueCode: CS_0aefdfec-022e-4ac9-a84b-83c8ea2e0fd0, CharacteristicID: 76c4e767-ce7b-4675-a178-d832839b322f}</Message>
<Context>
<EntityUniqueCode>CS_0aefdfec-022e-4ac9-a84b-83c8ea2e0fd0</EntityUniqueCode>
<CharacteristicID>76c4e767-ce7b-4675-a178-d832839b322f</CharacteristicID>
</Context>
</Response>

You need to choose correct stream depending on your response status. here is an example how you can do this:
BufferedReader br = null;
int statusCode = conn.getResponseCode();
if (statusCode>299){
br = new BufferedReared(new InputStreamReader(conn.getErrorStream()));
} else {
br = new BufferedReared(new InputStreamReader(conn.getInputStream()));
}

Related

java rest call response body missing in case of bad request

I am hitting below url using any rest client and I get the api Response :400 Bad Request with response body
INPUT param
POST http://SOME.IP:8008/equipment_api/F0-03-8C-C3-D3-CC/832
HEADERS
Content-Type application/json
X-RequestID 1234
BODY
{
"items":[{"updateValue":1, "updateKey": "RESETDEV"}],
"sync":"false"
}
Response :400 Bad Request
{
"error": "RESETDEV is not a valid key."
}
But java simple client does not show the response body.. below is java code.. it just give 400 bad req.
public static void main(String[] args) {
try {
String urlParameters = " {\r\n" +
"\"items\":[{\"updateValue\":\"Hi\", \"updateKey\": \"RESETDEV\"}],\r\n" +
"\"sync\":false\r\n" +
"}";
URL url = new URL("http://SOME.IP:8008/equipment_api/F0-03-8C-C3-D3-CC/832");
URLConnection conn = url.openConnection();
conn.setRequestProperty("content-type", "application/json");
conn.setRequestProperty("X-RequestID", "1234");
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
writer.close();
reader.close();
}catch(Exception ex) {
System.out.println("some error :: "+ex.toString());
}
}
Try to use following code
final String uri = "http://SOME.IP:8008/equipment_api/F0-03-8C-C3-D3-CC/832";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("X-RequestID", "1234");
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
System.out.println(result);
Wrap with Try Catch.
May it is useful to you. It will work
public static void main(String[] args) {
try {
String urlParameters = " {\r\n" +
"\"items\":[{\"updateValue\":\"Hi\", \"updateKey\":
\"RESETDEV\"}],\r\n" +
"\"sync\":false\r\n" +
"}";
URL url = new URL("http:http://SOME.IP:8008/equipment_api/F0-03-
8C-C3-D3-CC/832");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("content-type", "application/json");
con.setRequestProperty("X-RequestID", "1234");
con.setDoOutput(true);
OutputStreamWriter writer = new
OutputStreamWriter(con.getOutputStream());
writer.write(urlParameters);
writer.flush();
String line;
//BufferedReader reader = new BufferedReader(new
InputStreamReader(con.getInputStream()));
InputStream is = con.getInputStream();
if(con.getResponseCode() >= 200 && 299 <= con.getResponseCode()) {
is = con.getInputStream();
}else {
is = con.getErrorStream();
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(is,
"utf-8"))) {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
writer.close();
// br.close();
}catch(Exception ex) {
System.out.println("some error :: "+ex.toString());
}
}

Http post request parameters limit

I'm try to pass 19(images) parameters to htttp post request, but when I put more then 9 params, my app don't do the upload to server, I recheck all the code and is ok, server side is ok also.
#Override
protected String doInBackground(Void... params) {
Log.d("SETIMAGE", "IMAGEM DOINBACKGROUND INIT");
RequestHandler rh = new RequestHandler();
HashMap<String,String> param = new HashMap<String,String>();
param.put(KEY_ID,id);
param.put(KEY_CHAMADO,chamado);
param.put(FACHADA,imageFachada);
param.put(RADIO,imageRadio);
param.put(SUPORTE,imageSuporte);
param.put(MASTRO,imageMastro);
param.put(ISOLAMENTO,imageIsolamento);
param.put(INFRAEXT1,imageInfraExt1);
param.put(INFRAEXT2,imageInfraExt2);
param.put(INFRAINT1,imageInfraInt1);
param.put(INFRAINT2,imageInfraInt2);
param.put(CONECTOREXT,imageConectorExt);
param.put(CONECTORINT,imageConectorInt);
param.put(SALATEC,imageSalaTec);
param.put(RACK,imageRack);
param.put(IDU,imageIDU);
param.put(TOMADAIDU,imageTomadaIDU);
param.put(AZIMUTE,imageAzimute);
param.put(GPS,imageGPS);
param.put(MTCABOEXT,imageMtCaboExt);
param.put(MTCABOINT,imageMtCaboInt);
String result = rh.sendPostRequest(UploadUrl, param);
Log.d("RESULT", result);
return result;
}
This is via RequestHandler.class
public String sendPostRequest(String requestURL, HashMap<String, String> postDataParams) {
//Creating a URL
URL url;
//StringBuilder object to store the message retrieved from the server
StringBuilder sb = new StringBuilder();
try {
//Initializing Url
url = new URL(requestURL);
//Creating an httmlurl connection
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//Configuring connection properties
conn.setReadTimeout(150000);
conn.setConnectTimeout(150000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
//Creating an output stream
OutputStream os = conn.getOutputStream();
//Writing parameters to the request
//We are using a method getPostDataString which is defined below
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
sb = new StringBuilder();
String response;
//Reading server response
while ((response = br.readLine()) != null) {
sb.append(response);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
I need to pass all images to upload to server. But it's ok only when I pass 9 param.put
You should consider using Retrofit, which allows to upload huge size files in chunks and has more flexibility than most libraries.

Getting response code 400 when trying to get access token from Azure AD

I am implementing azure for my web application and trying to get access token by following there openId connect tutorial
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code
And when i am requesting to get the access token, i am always getting bad request 400
Request to get access token :
POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=2d4d11a2-f814-46a7-890a-274a72a7309e
&code=AwABAAAAvPM1KaPl.......
&redirect_uri=https%3A%2F%2Flocalhost%2Fmyapp%2F
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=p#ssw0rd
here is my code :
public static String post( String endpoint,
Map<String, String> params) {//YD
StringBuffer paramString = new StringBuffer("");
//if(!Utilities.checkInternetConnection(context)){
// return XMLHandler.getXMLForErrorCode(context, JSONHandler.ERROR_CODE_INTERNET_CONNECTION);
//}
Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
StringBuffer tempBuffer = new StringBuffer("");
String paramval;
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
if (param != null) {
if (paramString.length() > 0) {
paramString.append("&");
}
System.out.println( "post key : " + param.getKey());
String value;
try {
paramval = param.getValue();
if(paramval!=null)
value = URLEncoder.encode(paramval, "UTF-8");
else
value = "";
} catch (UnsupportedEncodingException e) {
value = "";
e.printStackTrace();
}
paramString.append(param.getKey()).append("=")
.append(value);
}
}
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(endpoint);
String data = "";
try {
// Add your data
// httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs))
//httppost.addHeader("Host", host);
httppost.addHeader("Content-Type",
"application/x-www-form-urlencoded");
if (!paramString.equals("")) {
if (tempBuffer.length() > 0) {
data = data + tempBuffer.toString();
}
data = data + paramString.toString();
if (data.endsWith("&")) {
data = data.substring(0, data.length() - 1);
}
httppost.setEntity(new ByteArrayEntity(data.getBytes()));
}
System.out.println( "post Stringbuffer : " + data);
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
int statuscode = response.getStatusLine().getStatusCode();
System.out.println("Response code : " + statuscode);
if (statuscode != 200) {
return null;
}
HttpEntity entity = response.getEntity();
InputStream in = null;
if (entity != null) {
in = entity.getContent();
}
if (in != null) {
StringBuilder builder = new StringBuilder();
String line;
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(in, "UTF-8"));
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} finally {
in.close();
}
String response2 = builder.toString();
System.out.println("response :" + response2);
retrycount = 0;
return response2;
}
}
catch(UnknownHostException e){
e.printStackTrace();
return null;
}
catch (EOFException eof) {
if (retrycount < max_retry) {
eof.printStackTrace();
post( endpoint, params);
retrycount = 1;
}
} catch (Throwable th) {
throw new IOException("Error in posting :" + th.getMessage());
}
retrycount = 0;
return null;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Please help me with this
Thanks in Advance
Have you ensured the redirect uri passed to /token is the same as the one you passed to /authorize
I believe, it will help if you can test the OAuth auth code flow with your current client id, secret and scope using Postman tool in order to rule out bad configuration.
Please refer to the code below to request AuthorizationCode.
public static void getAuthorizationCode() throws IOException {
String encoding = "UTF-8";
String params = "client_id=" + clientId
+ "&response_type=" + reponseType
+ "&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F"
+ "&response_mode=query"
+ "&resource=https%3A%2F%2Fgraph.windows.net"
+ "&state=12345";
String path = "https://login.microsoftonline.com/" + tenantId + "/oauth2/authorize";
byte[] data = params.getBytes(encoding);
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
conn.setConnectTimeout(5 * 1000);
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
BufferedReader br = null;
if (conn.getResponseCode() != 200) {
br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
} else {
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
}
System.out.println("Response body : " + br.readLine());
}
Then you could get access token using the AuthorizationCode you got and get refresh code using the code below.
public static void getToken(String refreshToken) throws IOException {
String encoding = "UTF-8";
String params = "client_id=" + clientId + "&refresh_token=" + refreshToken
+ "&grant_type=refresh_token&resource=https%3A%2F%2Fgraph.windows.net";
String path = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
byte[] data = params.getBytes(encoding);
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
conn.setConnectTimeout(5 * 1000);
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
BufferedReader br = null;
if (conn.getResponseCode() != 200) {
br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
} else {
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
}
System.out.println("Response body : " + br.readLine());
}
Hope it helps you.

I am getting 411 HTTP Error while using POST method in Java

I am facing a problem while using POST Method in Java nowadays. I am receiving
Exception in thread "main" java.lang.RuntimeException: Server returned HTTP response code: 411 for URL.
I couldn't find any available document anywhere. None of them were useful. How do I fix it?
My code
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class req {
public static void main(String[] args) {
sendPostRequest(requestURL);
}
private static String sendPostRequest(String requestUrl) {
StringBuilder jsonString = new StringBuilder();
try {
URL url = new URL(requestUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
byte[] data = requestUrl.getBytes("UTF-8");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Content-Length", String.valueOf(data.length));
connection.setRequestProperty("Authorization", "Basic " + "usename:password");
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
jsonString.append(line);
}
br.close();
connection.disconnect();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
return jsonString.toString();
}
}
Perfectly working method:
public String sendPostRequest(String requestURL, HashMap<String, String> postDataParams) {
URL url;
String response = "";
try {
url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
int responseCode=conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
response = br.readLine();
}
else {
response="Error Registering";
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for(Map.Entry<String, String> entry : params.entrySet()){
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
If you are returning a JSON in your response:
public JSONObject getPostResult(String json){
if(!json.isEmpty()) {
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON_ERROR", "Error parsing data " + e.toString());
}
}
return jObj;
}
If you are still having trouble, maybe this will help. I did not test, machine does not have java installed.
You should also set all other headers that you need.
public static String PostRequest(String requestUrl, String username, String password) {
StringBuilder jsonString = new StringBuilder();
HttpURLConnection connection = null;
try {
URL url = new URL(requestUrl);
connection = (HttpURLConnection)url.openConnection();
byte[] authData = Base64.encode((username + password).getBytes());
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Authorization", "Basic " + new String(authData));
connection.setRequestProperty("Content-Length", String.valueOf(authData.length));
try (DataOutputStream writer = new DataOutputStream(connection.getOutputStream())) {
writer.writeBytes("REPLACE ME WITH DATA TO BE WRITTEN");
writer.flush();
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String data = null;
while ((data = reader.readLine()) != null) {
jsonString.append(data);
}
}
} catch (IOException ex) {
//Handle exception.
} finally {
if (connection != null)
connection.disconnect();
}
return jsonString.toString();
}
You should send empty data in body if you are using post method.
For example if you are using json data you need to send "{}"
public void Post() throws Exception {
StringBuffer d = new StringBuffer();
String da = "ClearanceDate=2020-08-31&DepositeDate=2020-08-31&BankTransactionNo=UATRYU56789";
URL url = new URL("https://abcd/AddReceipt?" + da);
byte[] postDataBytes = ("https://abcd/AddReceipt?" + da).toString()
.getBytes("UTF-8");
System.out.println("Data--" + postDataBytes);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
// con.setRequestProperty("User-Agent",
// "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
con.setRequestProperty("Content-Length",
String.valueOf(postDataBytes.length));
con.setRequestProperty(
"Authorization",
"Bearer "
+ "o731WGgp1d913ZOYivnc55yOg0y1Wk7GsT_mnCUKOJf1VChYOdfRjovAxOhyyPKU93ERue6-l9DyG3IP29ObsCNTFr4lGZOcYAaR96ZudKgWif1UuSfVx4AlATiOs9shQsGgb1oXN_w0NRJKvYqD0LLsZLstBAzP1s5PZoaS9c6MmO32AV47FUvxRT6Tflus5DBDHji3N4f1AM0dShbzmjkBCzXmGzEDnU6Jg1Mo5kb884kParngKADG5umtuGbNzChQpMw_A0SyEYaUNh18pXVmnNhqM3Qx5ZINwDEXlYY");
con.setRequestProperty("Accept", "application/json");
con.setDoInput(true);
con.setDoOutput(true);
con.getOutputStream().write(postDataBytes);
int status = con.getResponseCode();
System.out.println("Response status: " + status + "|"
+ con.getResponseMessage());
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
con.disconnect();
System.out.println("Response status: " + status);
System.out.println(content.toString());
System.out.print("Raw Response->>" + d);
}

Error trying to post JSON data to Android Device

I've followed the tutorial here in an attempt to send data to an android device. I've whittled my Java class down to this:
public class App {
public static void main( String[] args ) {
try {
String apiKey = "api key generated in Google Developer Console...";
String deviceId = "Device Id generated, retrieved directly from logcat, as per tutorial...";
Content content = new Content();
content.addRegId(deviceId);
content.createData("Title", "Notification Message");
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key=" + apiKey);
conn.setDoOutput(true);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
mapper.writeValue(wr, content);
wr.flush();
wr.close();
int responseCode = conn.getResponseCode();
System.out.println(responseCode == 200 ? responseCode + ". This is the response we want..." : responseCode + ". This is not the response we want...");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
and this is my Content class:
public class Content implements Serializable{
private List<String> registration_ids;
private Map<String,String> data;
public void addRegId(String regId) {
if(registration_ids == null)
registration_ids = new LinkedList<String>();
registration_ids.add(regId);
}
public void createData(String title, String message) {
if (data == null)
data = new HashMap<String,String>();
data.put("title", title);
data.put("message", message);
}
}
I'm getting a 400 response code
java.io.IOException: Server returned HTTP response code: 400 for URL: https://android.googleapis.com/gcm/send
I'm sure I'm missing something small, but I can't see where it is.

Categories