title: HTTP 400 When Trying to Send HTTP Post GraphQL Query using HttpClient in Java
body: <p>Have a post query for an external GraphQL server which works in Postman Pro setup as a Pre-request Script.</p>
  
  <p>Am trying to hit an external GraphQL server using HttpClient.</p>
  
  <p>Maven dependencies pom.xml:</p>
  
  <pre><code>&lt;!-- Apache Commons --&gt;
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.commons&lt;/groupId&gt;
      &lt;artifactId&gt;commons-lang3&lt;/artifactId&gt;
      &lt;version&gt;3.6&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.httpcomponents&lt;/groupId&gt;
      &lt;artifactId&gt;httpclient&lt;/artifactId&gt;
      &lt;version&gt;4.2.5&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;commons-codec&lt;/groupId&gt;
      &lt;artifactId&gt;commons-codec&lt;/artifactId&gt;
      &lt;version&gt;1.6&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.httpcomponents&lt;/groupId&gt;
      &lt;artifactId&gt;httpcore&lt;/artifactId&gt;
      &lt;version&gt;4.2.4&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;commons-logging&lt;/groupId&gt;
      &lt;artifactId&gt;commons-logging&lt;/artifactId&gt;
      &lt;version&gt;1.1.1&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.httpcomponents&lt;/groupId&gt;
      &lt;artifactId&gt;httpclient-cache&lt;/artifactId&gt;
      &lt;version&gt;4.2.5&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;org.apache.httpcomponents&lt;/groupId&gt;
      &lt;artifactId&gt;httpmime&lt;/artifactId&gt;
      &lt;version&gt;4.2.5&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;!-- Google Code --&gt;
  &lt;dependency&gt;
      &lt;groupId&gt;com.googlecode.json-simple&lt;/groupId&gt;
      &lt;artifactId&gt;json-simple&lt;/artifactId&gt;
      &lt;version&gt;1.1.1&lt;/version&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>Hardcoded the pre-request script as follows:</p>
  
  <p>GetDataAsRequest.java</p>
  
  <pre><code>public class GetDataAsRequest {
      private static final String GET_DATA_REQUEST_TEMPLATE = 
      "query {" 
          + "    viewer {     "
          + "        data(id: \"10045701-2017-41a4-33f4-bf8481cf01dc\") {" + 
          "            id"
          + "            createdDate" 
          + "            lastModifiedDate" 
          + "            abbreviation"
          + "            cityStateRegion" 
          + "        }"
          + "    }"
          + "}";
      }
  
      public static String generateQuery() {
          return String.format(GET_DATA_REQUEST_TEMPLATE);
      }
  }
  </code></pre>
  
  <p>MyController:</p>
  
  <pre><code>public class MyController {
  
      private static final String EXTERNAL_API_URL = "https://sample-api.com"
  
      public static void main (String args []) {
  
          // Generate Access Token
          String accessToken = OAuth2Client.generateAccessToken();
          DefaultHttpClient httpClient = new DefaultHttpClient();
          HttpPost postRequest = new HttpPost(EXTERNAL_API_URL);
          StringEntity postBody = new StringEntity(GetDataAsRequest.generateQuery());
          postBody.setContentType("application/json");
          postRequest.addHeader("Authorization", "Bearer " + accessToken);
          postRequest.setEntity(postBody);
          HttpResponse response = httpClient.execute(postRequest);
  
          if (response.getStatusLine().getStatusCode() != 201) {
              throw new RuntimeException("Failed : HTTP error code : " + response.getStatusLine().getStatusCode());
          }
  
          BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
  
          String output;
          System.out.println("Output from Server .... \n");
          while ((output = br.readLine()) != null) {
              System.out.println(output);
          }
          httpClient.getConnectionManager().shutdown();
          } 
          catch (MalformedURLException e) {
              e.printStackTrace();
          } 
          catch (IOException e) {
              e.printStackTrace();
          }
      }
  </code></pre>
  
  <p>Although the same OAuthToken and HTTP post query works when I copy it from stdin (console) into a Postman call, I keep getting an HTTP 400 when trying to emulate the same call using HttpClient inside a Java program:</p>
  
  <pre><code>03:25:30.690 [main] DEBUG org.apache.http.impl.conn.BasicClientConnectionManager - Get connection for route {s}-&gt;https://https://sample-api.com
  03:25:30.751 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnectionOperator - Connecting to https://sample-api.com:443
  03:25:30.943 [main] DEBUG org.apache.http.client.protocol.RequestAddCookies - CookieSpec selected: best-match
  03:25:30.950 [main] DEBUG org.apache.http.client.protocol.RequestAuthCache - Auth cache not set in the context
  03:25:30.950 [main] DEBUG org.apache.http.client.protocol.RequestTargetAuthentication - Target auth state: UNCHALLENGED
  03:25:30.951 [main] DEBUG org.apache.http.client.protocol.RequestProxyAuthentication - Proxy auth state: UNCHALLENGED
  03:25:30.951 [main] DEBUG org.apache.http.impl.client.DefaultHttpClient - Attempt 1 to execute request
  03:25:30.951 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnection - Sending request: POST /v1/oauth/token HTTP/1.1
  03:25:30.951 [main] DEBUG org.apache.http.wire - &gt;&gt; "POST /v1/oauth/token HTTP/1.1[\r][\n]"
  03:25:30.952 [main] DEBUG org.apache.http.wire - &gt;&gt; "Content-Length: 119[\r][\n]"
  03:25:30.952 [main] DEBUG org.apache.http.wire - &gt;&gt; "Content-Type: application/x-www-form-urlencoded; charset=UTF-8[\r][\n]"
  03:25:30.952 [main] DEBUG org.apache.http.wire - &gt;&gt; "Host: https://sample-api.com[\r][\n]"
  03:25:30.952 [main] DEBUG org.apache.http.wire - &gt;&gt; "Connection: Keep-Alive[\r][\n]"
  03:25:30.952 [main] DEBUG org.apache.http.wire - &gt;&gt; "User-Agent: Apache-HttpClient/4.2.5 (java 1.5)[\r][\n]"
  03:25:30.952 [main] DEBUG org.apache.http.wire - &gt;&gt; "[\r][\n]"
  03:25:30.952 [main] DEBUG org.apache.http.headers - &gt;&gt; POST /v1/oauth/token HTTP/1.1
  03:25:30.952 [main] DEBUG org.apache.http.headers - &gt;&gt; Content-Length: 119
  03:25:30.952 [main] DEBUG org.apache.http.headers - &gt;&gt; Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  03:25:30.952 [main] DEBUG org.apache.http.headers - &gt;&gt; Host: https://sample-api.com
  03:25:30.952 [main] DEBUG org.apache.http.headers - &gt;&gt; Connection: Keep-Alive
  03:25:30.953 [main] DEBUG org.apache.http.headers - &gt;&gt; User-Agent: Apache-HttpClient/4.2.5 (java 1.5)
  03:25:30.953 [main] DEBUG org.apache.http.wire - &gt;&gt; "grant_type=client_credentials&amp;client_id=fghuXeULFBdW4B1dmRY0MhROMRQnlumk&amp;client_secret=MM2banXEq2R1GhRvIQ2d2AKRx0SORvb4"
  03:25:31.132 [main] DEBUG org.apache.http.wire - &lt;&lt; "HTTP/1.1 200 OK[\r][\n]"
  03:25:31.134 [main] DEBUG org.apache.http.wire - &lt;&lt; "X-Application-Context: application:prod[\r][\n]"
  03:25:31.134 [main] DEBUG org.apache.http.wire - &lt;&lt; "Content-Type: application/json[\r][\n]"
  03:25:31.134 [main] DEBUG org.apache.http.wire - &lt;&lt; "Cache-Control: no-store[\r][\n]"
  03:25:31.134 [main] DEBUG org.apache.http.wire - &lt;&lt; "Pragma: no-cache[\r][\n]"
  03:25:31.134 [main] DEBUG org.apache.http.wire - &lt;&lt; "Accept-Ranges: bytes[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "X-Cache-Hits: 0[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "X-Timer: S1525774921.421988,VS0,VE41[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "Date: Tue, 08 May 2018 10:22:01 GMT[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "Content-Length: 325[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "Connection: keep-alive[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "X-Sample-APP: sso[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "Access-Control-Allow-Headers: Authorization,Content-Type[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "Access-Control-Allow-Methods: PUT,POST,OPTIONS,GET,PATCH,DELETE[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "Access-Control-Allow-Origin: *[\r][\n]"
  03:25:31.135 [main] DEBUG org.apache.http.wire - &lt;&lt; "[\r][\n]"
  03:25:31.136 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnection - Receiving response: HTTP/1.1 200 OK
  03:25:31.136 [main] DEBUG org.apache.http.headers - &lt;&lt; HTTP/1.1 200 OK
  03:25:31.136 [main] DEBUG org.apache.http.headers - &lt;&lt; X-Application-Context: application:prod
  03:25:31.136 [main] DEBUG org.apache.http.headers - &lt;&lt; Content-Type: application/json
  03:25:31.136 [main] DEBUG org.apache.http.headers - &lt;&lt; Cache-Control: no-store
  03:25:31.136 [main] DEBUG org.apache.http.headers - &lt;&lt; Pragma: no-cache
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; Accept-Ranges: bytes
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; X-Served-By: cache-sample-las9320
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; X-Cache-Hits: 0
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; X-Timer: S1525774921.421988,VS0,VE41
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; Date: Tue, 08 May 2018 10:22:01 GMT
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; Content-Length: 325
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; Connection: keep-alive
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; X-Sample-APP: sso
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; Access-Control-Allow-Headers: Authorization,Content-Type
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; Access-Control-Allow-Methods: PUT,POST,OPTIONS,GET,PATCH,DELETE
  03:25:31.138 [main] DEBUG org.apache.http.headers - &lt;&lt; Access-Control-Allow-Origin: *
  03:25:31.141 [main] DEBUG org.apache.http.impl.client.DefaultHttpClient - Connection can be kept alive indefinitely
  03:25:31.147 [main] DEBUG org.apache.http.wire - &lt;&lt; "{"access_token":"fkMmGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6bnVsbCwiZGV2aWNlSWQiOm51bGwsImNsaWVudElkIjoiaUxIdVhlVUxGQmRXNEIxZG1SWTBNaFJPTVJRbmxmZUsiLCJhZElkIjpudWxsLCJleHAiOjE1MjU3Nzg1MjEsImlhdCI6MTUyNTc3NDkyMX0.U3gacgf7a8hlwCuCn6yGXc0z6E5Zrwgii3B_77xFlyo","token_type":"Bearer","expires_in":3600,"refresh_token":null,"scope":null}"
  03:25:31.147 [main] DEBUG org.apache.http.impl.conn.BasicClientConnectionManager - Releasing connection org.apache.http.impl.conn.ManagedClientConnectionImpl@2ddc8ecb
  03:25:31.147 [main] DEBUG org.apache.http.impl.conn.BasicClientConnectionManager - Connection can be kept alive indefinitely
  Exception in thread "main" java.lang.RuntimeException: Failed : HTTP error code : 400
  </code></pre>
  
  <p>Is this returning an HTTP 400 because my request body is wrong in some way?</p>
  
  <p>Is there an easier way to obtain JSON responses via GraphQL's Java libs:</p>
  
  <pre><code>&lt;!-- GraphQL --&gt;
  &lt;dependency&gt;
      &lt;groupId&gt;com.graphql-java&lt;/groupId&gt;
      &lt;artifactId&gt;graphql-java&lt;/artifactId&gt;
      &lt;version&gt;8.0&lt;/version&gt;
  &lt;/dependency&gt;
  
  &lt;dependency&gt;
      &lt;groupId&gt;com.graphql-java&lt;/groupId&gt;
      &lt;artifactId&gt;graphql-java-tools&lt;/artifactId&gt;
      &lt;version&gt;5.0.0&lt;/version&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>A lot of examples on the Internet show how to setup and external GraphQL server, what I need is to learn how to use the GraphQL Java libs serving as a client library to parse and obtain the right GraphQL response from an external server...</p>
  
  <p>This is returning correctly from Postman Pro and curl but not using HttpClient.</p>
  
  <p>What am I possibly doing wrong?</p>