title: How do I get a byte[] (image) from a webservice using micronaunt HttpClient
body: <p>I am porting a Grails 3.1 library for using some internal webservices to Grails 4.0.   One of the services provides an image of a requested employee upon request.  I am having difficulty implementing the (micronaut) HttpClient code to process the request - specifically to get a proper <code>byte[]</code> that is the returned image.  </p>
  
  <p>A simple curl command on the command line works with the service:</p>
  
  <pre><code>curl -D headers.txt -H 'Authorization:Basic &lt;encodedKeyHere&gt;' https:&lt;serviceUrl&gt; &gt;&gt; image.jpg
  </code></pre>
  
  <p>and the image is correct.  The header.txt is: </p>
  
  <pre><code>HTTP/1.1 200 
  content-type: image/jpeg;charset=UTF-8
  date: Tue, 27 Aug 2019 20:05:43 GMT
  x-ratelimit-limit: 100
  X-RateLimit-Limit: 100
  X-RateLimit-Remaining: 99
  x-ratelimit-remaining: 99
  X-RateLimit-Reset: 38089
  x-ratelimit-reset: 15719
  Content-Length: 11918
  Connection: keep-alive
  </code></pre>
  
  <p>The old library uses the <code>groovyx.net.http.HTTPBuilder</code> and simply does: </p>
  
  <pre class="lang-java prettyprint-override"><code>http.request(Method.GET, ContentType.BINARY) {
              uri.path = photoUrlPath
              uri.query = queryString
              headers.'Authorization' = "Basic $encoded".toString()
              response.success = { resp, inputstream -&gt;
                  log.info "response status: ${resp.statusLine}"                
                  return ['status':resp.status, 'body':inputstream.getBytes()]
              }
              response.failure = { resp -&gt;
                  return ['status':resp.status, 
                          'error':resp.statusLine.reasonPhrase, 
                           body:resp.getEntity().getContent().getText()]
              }
          }
  </code></pre>
  
  <p>so returning the bytes from an inputStream.  This works.    </p>
  
  <p>I've tried several things using the micronaut HttpClient, both with the low level API and with the declarative API. </p>
  
  <p>A simple example with the declarative API:</p>
  
  <pre class="lang-java prettyprint-override"><code>
      @Get(value='${photo.ws.pathurl}', produces = MediaType.IMAGE_JPEG)
      HttpResponse&lt;byte[]&gt; getPhoto(@Header ('Authorization') String authValue, 
                                    @QueryValue("emplId") String emplId)
  
  </code></pre>
  
  <p>And than in the Service:</p>
  
  <pre class="lang-java prettyprint-override"><code>    HttpResponse&lt;byte[]&gt; resp = photoClient.getPhoto(getBasicAuth(),emplId)
      def status = resp.status()            // code == 200 --&gt; worked 
      def bodyStrOne = resp.getBody()       // nope: get Optional.empty 
      // Tried different getBody(class) -&gt; Can't figure out where the byte[]s are   
      // For example can do:
      def buf = resp.getBody(io.netty.buffer.ByteBuf).value // Why need .value?
      def bytes = buf.readableBytes()       // Returns 11918 --&gt; the expected value
      byte[] ans = new byte[buf.readableBytes()]
      buf.readBytes(ans)    // Throws exception: io.netty.util.IllegalReferenceCountException: refCnt: 0
  
  </code></pre>
  
  <p>This "works" but the returned String looses some encoding that I can't reverse:</p>
  
  <pre class="lang-java prettyprint-override"><code>   // Client - use HttpResponse&lt;String&gt;
     @Get(value='${photo.ws.pathurl}', produces = MediaType.IMAGE_JPEG)
     HttpResponse&lt;String&gt; getPhoto(@Header ('Authorization') String authValue, 
                                    @QueryValue("emplId") String emplId)
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>   // Service 
     HttpResponse&lt;String&gt; respOne = photoClient.getPhoto(getBasicAuth(),emplId)
     def status = respOne.status()                  // code == 200 --&gt; worked 
     def bodyStrOne = respOne.getBody(String.class) // &lt;-- RETURNS DATA..just NOT an Image..or encoded or something
     String str = bodyStrOne.value                  // get the String data  
     // But these bytes aren't correct
     byte[] ans = str.getBytes()                    // NOT an image..close but not.
     // str.getBytes(StandardCharsets.UTF_8) or any other charset doesn't work 
  
  </code></pre>
  
  <p>Everything I've tried with the ByteBuf classes throws the <code>io.netty.util.IllegalReferenceCountException: refCnt: 0</code> exception.  </p>
  
  <p>Any direction/help would be greatly appreciated.  </p>
  
  <p>Running: </p>
  
  <pre><code>    Grails   4.0 
      JDK      1.8.0_221 
      Groovy   2.4.7
      Windows  10
      IntellJ  2019.2  
  </code></pre>