Search code examples
javacurlhttpurlconnection

Java executing curl command using HttpURLConnection returns 204 (HTTP_NO_CONTENT)


I am using Java 11. I have the the following curl command, when I execute on the command line:

curl --location --request GET 'http://xxx.xxx.co.za:8080/document/details/Select+docId+From+%27Workflow+Club%2FCustomer+Invoices%27+where+recursive+%3D+true+and+invoice_number+%3D%271221669023%27' --header 'Authorization: Basic xxx'

Returns the following:

{errorMessage: 'PaperTrail API only available in enterprise edition'}

However, when I try execute the same URL in a Java application using HttpURLConnection, it returns a blank response.

private static final String USER_AGENT = "Mozilla/5.0";

private static final String GET_URL = "http://xxx.xxx.co.za:8080/document/details/";
private static final String GET_URL_QRY = "Select docId From 'Workflow Club/Customer Invoices' where recursive = true and invoice_number =':1'";
private static final String GET_AUTH_ENC = "Basic xxx";

@Override
public String getDocId(Long invoiceNumber) {
    String get_url_qry = StringUtils.replace(GET_URL_QRY, ":1", Long.toString(invoiceNumber));
    get_url_qry = URLEncoder.encode(get_url_qry, StandardCharsets.UTF_8);
    final String get_url = GET_URL+get_url_qry;
    try {
        URL url = new URL(get_url);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestProperty("Authorization", GET_AUTH_ENC);
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", USER_AGENT);
        int responseCode = con.getResponseCode();
        logger.info(get_url+" -> GET Response Code :: " + responseCode);
        if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { // success
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            String resp = response.toString();
            logger.info(responseCode+" Response: '"+resp+"'.");
        } else {
            logger.error("GET request did not work (responseCode: "+responseCode+").");
        }
    } catch (MalformedURLException e) {
        logger.error("MalformedURLException creating URL '"+get_url+"'. "+e.getMessage());
    } catch (IOException e) {
        logger.error("IOException creating connection from URL '"+get_url+"'. "+e.getMessage());
    }
    return null;
}

Outputs the following with a blank response:

204 Response: ''.

Question

How do I get the Java application to also return the same as the command line call?

UPDATE

I have a different POST url, that I need to call too, and I can call it successfully. So there's something wrong with my GET call.

private static final String USER_AGENT = "Mozilla/5.0";

E.g. GET call that returns a 204, with no content.

private String getDocId(Long invoiceNumber) {
    String get_url_qry = StringUtils.replace(GET_URL_QRY, ":1", Long.toString(invoiceNumber));
    get_url_qry = URLEncoder.encode(get_url_qry, StandardCharsets.UTF_8);
    final String get_url = GET_URL+get_url_qry;
    try {
        URL url = new URL(get_url);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestProperty("Authorization", GET_AUTH_ENC);
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        Map<String,String> data = handleResponse(con);
        return data.get("docId");
    } catch (MalformedURLException e) {
        logger.error("MalformedURLException creating URL '"+get_url+"'. "+e.getMessage());
    } catch (IOException e) {
        logger.error("IOException creating connection from URL '"+get_url+"'. "+e.getMessage());
    }
    return null;
}

The POST call, that returns a 200, and the expected content.

private String getDocLink(String docId) {
    if (StringUtils.isNotBlank(docId)) {
        try {
            URL url = new URL(POST_URL);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestProperty("Authorization", GET_AUTH_ENC);
            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", USER_AGENT);
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            byte[] postDataBytes = getPostData(docId);
            con.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
            con.setDoOutput(true);
            con.getOutputStream().write(postDataBytes);
            Map<String,String> data = handleResponse(con);
            return data.get("url");
        } catch (IOException e) {
            logger.error("IOException creating connection from URL '"+POST_URL+"'. "+e.getMessage());
        }
    } else {
        logger.error("No docId provided when trying to get a document link.");
    }
    return null;
}

So seeing the that POST call works, I think I must be doing something wrong with the GET call.


Solution

  • Did you try, setting the same user agent in your Java Code, cURL would use? something like curl/7.37.0? As far as I can tell, that should be all, what differs. Aside cURL following redirects. But as there is no redirect, I guess it might be the User Agent making a difference.

    There are a lot of server applications, behaving differently, when they are called by a browser (Like you make it think by setting the User-Agent to Mozilla/5.0), instead of some other application, like cURL.