我正在将一个 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