【发布时间】:2019-08-28 18:54:17
【问题描述】:
我正在将一个 Grails 3.1 库移植到 Grails 4.0,以便使用一些内部 Web 服务。其中一项服务根据请求提供所请求员工的图像。我在实现(micronaut)HttpClient 代码来处理请求时遇到了困难——特别是要获得正确的byte[],即返回的图像。
命令行上的一个简单 curl 命令可以与服务一起使用:
curl -D headers.txt -H 'Authorization:Basic <encodedKeyHere>' https:<serviceUrl> >> image.jpg
而且图像是正确的。 header.txt 是:
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
旧库使用groovyx.net.http.HTTPBuilder 并且简单地这样做了:
http.request(Method.GET, ContentType.BINARY) {
uri.path = photoUrlPath
uri.query = queryString
headers.'Authorization' = "Basic $encoded".toString()
response.success = { resp, inputstream ->
log.info "response status: ${resp.statusLine}"
return ['status':resp.status, 'body':inputstream.getBytes()]
}
response.failure = { resp ->
return ['status':resp.status,
'error':resp.statusLine.reasonPhrase,
body:resp.getEntity().getContent().getText()]
}
}
所以从输入流返回字节。这行得通。
我已经使用 micronaut HttpClient 尝试了几件事,包括低级 API 和声明式 API。
声明式 API 的简单示例:
@Get(value='${photo.ws.pathurl}', produces = MediaType.IMAGE_JPEG)
HttpResponse<byte[]> getPhoto(@Header ('Authorization') String authValue,
@QueryValue("emplId") String emplId)
比在服务中:
HttpResponse<byte[]> resp = photoClient.getPhoto(getBasicAuth(),emplId)
def status = resp.status() // code == 200 --> worked
def bodyStrOne = resp.getBody() // nope: get Optional.empty
// Tried different getBody(class) -> 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 --> the expected value
byte[] ans = new byte[buf.readableBytes()]
buf.readBytes(ans) // Throws exception: io.netty.util.IllegalReferenceCountException: refCnt: 0
这“有效”,但返回的字符串丢失了一些我无法反转的编码:
// Client - use HttpResponse<String>
@Get(value='${photo.ws.pathurl}', produces = MediaType.IMAGE_JPEG)
HttpResponse<String> getPhoto(@Header ('Authorization') String authValue,
@QueryValue("emplId") String emplId)
// Service
HttpResponse<String> respOne = photoClient.getPhoto(getBasicAuth(),emplId)
def status = respOne.status() // code == 200 --> worked
def bodyStrOne = respOne.getBody(String.class) // <-- 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
我对 ByteBuf 类所做的一切尝试都会引发 io.netty.util.IllegalReferenceCountException: refCnt: 0 异常。
任何方向/帮助将不胜感激。
跑步:
Grails 4.0
JDK 1.8.0_221
Groovy 2.4.7
Windows 10
IntellJ 2019.2
【问题讨论】:
标签: download binary httpclient micronaut micronaut-client