Groovy HttpBuilder-NG请求响应体为空问题求解(Groovy 2.5.19)
如何在Groovy 2.5.19中用HttpBuilder-NG正确读取HTTP响应体?
你执行HTTP请求后,返回状态码200且显示存在响应体,但读取到的内容为空。以下是正确读取响应体的几种方法:
问题复现代码
@Grab(group='io.github.http-builder-ng', module='http-builder-ng-apache', version='1.0.4') import groovyx.net.http.* HttpBuilder http = HttpBuilder.configure { request.uri = 'https://stackoverflow.com' request.accept = ['text/html'] } http.get { response.success { FromServer fromServer -> println("Got status $fromServer.statusCode $fromServer.message") println("Has body: $fromServer.hasBody") try { List<String> bodyLines = fromServer.reader.withReader { it.readLines() } String body = bodyLines.join("\n") if (body.empty) { println("Body is empty.") } else { println("Body: $body") } } catch (Exception e) { println("Reading successful response failed. $e") } } }
输出:
Got status 200 OK Has body: true Body is empty.
正确解决方案
方法一:直接在success回调中接收响应体参数
HttpBuilder-NG的success回调支持接收第二个参数,即框架自动解析后的响应体。只需调整回调参数列表即可直接获取:
@Grab(group='io.github.http-builder-ng', module='http-builder-ng-apache', version='1.0.4') import groovyx.net.http.* HttpBuilder http = HttpBuilder.configure { request.uri = 'https://stackoverflow.com' request.accept = ['text/html'] } http.get { response.success { FromServer fromServer, String body -> println("Got status $fromServer.statusCode $fromServer.message") println("Has body: $fromServer.hasBody") if (body.empty) { println("Body is empty.") } else { println("Body snippet: ${body.take(500)}...") // 截取部分内容避免输出过长 } } }
方法二:显式指定响应解析器
如果需要自定义解析逻辑,可以显式设置response.parser来定义如何处理响应体:
@Grab(group='io.github.http-builder-ng', module='http-builder-ng-apache', version='1.0.4') import groovyx.net.http.* HttpBuilder http = HttpBuilder.configure { request.uri = 'https://stackoverflow.com' request.accept = ['text/html'] // 针对text/html类型自定义解析逻辑 response.parser('text/html') { FromServer fs, Object rawBody -> return rawBody instanceof String ? rawBody : fs.reader.text } } http.get { response.success { FromServer fromServer, String body -> println("Got status $fromServer.statusCode $fromServer.message") println("Has body: $fromServer.hasBody") println("Body snippet: ${body.take(500)}...") } }
方法三:通过reader读取(需禁用默认解析)
如果必须使用fromServer.reader读取,需要先禁用默认的响应解析,避免流被提前消费:
@Grab(group='io.github.http-builder-ng', module='http-builder-ng-apache', version='1.0.4') import groovyx.net.http.* HttpBuilder http = HttpBuilder.configure { request.uri = 'https://stackoverflow.com' request.accept = ['text/html'] // 禁用默认解析,保留reader可用 response.parser('text/html') { FromServer fs, Object body -> null } } http.get { response.success { FromServer fromServer -> println("Got status $fromServer.statusCode $fromServer.message") println("Has body: $fromServer.hasBody") try { String body = fromServer.reader.text if (body.empty) { println("Body is empty.") } else { println("Body snippet: ${body.take(500)}...") } } catch (Exception e) { println("Reading successful response failed. $e") } } }
说明
最推荐使用方法一,因为HttpBuilder-NG会自动根据请求的Accept头和响应的Content-Type头匹配合适的解析器,直接获取解析后的响应体最为简洁高效。
内容的提问来源于stack exchange,提问作者xehpuk
相关产品推荐
相关产品推荐

