0

I am writing to an HTTP POST endpoint using code like this.

When the response code is 200 everything is OK.

When the response code is 400 though I cannot get InputStream and read the response.

I am just getting an exception on the line marked with /// error !!!

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL: ... 
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1924)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1520)
    at com.test123.Main009.main(Main009.java:41)

So is there a way to read the response body even though the response code is 4xx ?

package com.test123;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Main009 {

    public static void main(String[] args) throws Exception {
        String username = "xxx";
        String password = "yyy";
        
        URL url = new URL("http://host/path");
        URLConnection uc = url.openConnection();
        HttpURLConnection http = (HttpURLConnection)uc;
        
        http.setRequestMethod("POST"); // PUT is another valid option
        http.setDoOutput(true);
        http.setDoInput(true);

        byte[] request = "{ id: \"test2\" }".getBytes(StandardCharsets.UTF_8);
        int length = request.length;

        http.setFixedLengthStreamingMode(length);
        
        String userpass = username + ":" + password;
        String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
        
        http.setRequestProperty ("Authorization", basicAuth);
        http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        // http.connect();
        
        try(OutputStream os = http.getOutputStream()) {
            os.write(request);
            os.flush();
            
            InputStream in = http.getInputStream(); /// error !!!  
            System.out.println(in);
        }
        

        
    }

}
peter.petrov
  • 38,363
  • 16
  • 94
  • 159

2 Answers2

1

In case of non-successful response codes, you have to read the body with HttpURLConnection.getErrorStream().

Rahul
  • 21
  • 5
-5

Yes, there is a way to read the response body even when the response code is in the 4xx range. In such cases, you can use the getErrorStream() method instead of getInputStream() to obtain the response body.

Here's an updated version of your code that handles both successful and error responses:

public static void main(String[] args) throws Exception {
    String username = "xxx";
    String password = "yyy";

    URL url = new URL("http://host/path");
    URLConnection uc = url.openConnection();
    HttpURLConnection http = (HttpURLConnection) uc;

    http.setRequestMethod("POST"); // PUT is another valid option
    http.setDoOutput(true);
    http.setDoInput(true);

    byte[] request = "{ id: \"test2\" }".getBytes(StandardCharsets.UTF_8);
    int length = request.length;

    http.setFixedLengthStreamingMode(length);

    String userpass = username + ":" + password;
    String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));

    http.setRequestProperty("Authorization", basicAuth);
    http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
    // http.connect();

    try (OutputStream os = http.getOutputStream()) {
        os.write(request);
        os.flush();

        int responseCode = http.getResponseCode();
        InputStream inputStream;
        if (responseCode >= 200 && responseCode < 300) {
            inputStream = http.getInputStream();
        } else {
            inputStream = http.getErrorStream();
        }

        // Read and process the response body
        byte[] responseBody = inputStream.readAllBytes();
        String response = new String(responseBody, StandardCharsets.UTF_8);
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response Body: " + response);
    }
}

In this updated code, we first obtain the response code using getResponseCode(). If the response code is in the 2xx range, we use getInputStream() as before. However, if the response code is in the 4xx range, we use getErrorStream() to get the input stream and read the response body.

I hope this helps!

Ayan Shah
  • 1
  • 2