【问题标题】:Retrieving the response body from an HttpClientResponse从 HttpClientResponse 检索响应正文
【发布时间】:2015-01-06 23:10:19
【问题描述】:

我正在尝试为我的 Dart 服务器应用程序编写一些测试,并且我一直在使用 HttpClient 类(以及相关的 HttpClientRequest 和 HttpClientResponse 类向服务器发出测试请求(请注意,我正在使用这些类,因为我需要 dart:io 包来运行服务器,所以我也不能导入 dart:html)。到目前为止,这一切进展顺利,我已经能够编写测试来检查服务器是否正常返回带有正确 HTTP 状态代码的响应。我用来进行这些测试调用的代码的基础如下:

Future<HttpClientResponse> makeServerRequest(String method, Uri uri, [String jsonData]) async {
  HttpClient client = new HttpClient();
  HttpClientRequest request = await client.openUrl(method, uri);
  request.write(jsonData);
  return request.close();
}

现在我需要编写一个测试来确保响应的主体,而不仅仅是状态码,是正确的。问题是我似乎找不到任何可以让我实际访问 HttpClient* 类中的响应主体的东西。到目前为止,我能找到的最接近的是 HttpClientResponse.contentLength 属性,但这只能告诉我响应正文有多大,而不是实际内容。

如何从这些请求中检索响应正文?或者,如果您做不到,是否可以通过其他方式在服务器端应用程序上发出请求,以便读取响应?

【问题讨论】:

    标签: dart


    【解决方案1】:

    HttpClientResponse 对象是一个Stream,因此您可以使用listen() 方法读取它:

    response.listen((List<int> data) {
      //data as bytes
    });
    

    您还可以使用来自dart:convert 的编解码器来解析数据。以下示例将响应内容读取到字符串:

    import 'dart:io';
    import 'dart:convert';
    import 'dart:async';
    
    Future<String> readResponse(HttpClientResponse response) {
      final completer = Completer<String>();
      final contents = StringBuffer();
      response.transform(utf8.decoder).listen((data) {
        contents.write(data);
      }, onDone: () => completer.complete(contents.toString()));
      return completer.future;
    }
    

    【讨论】:

    • 完美。我一直在努力寻找类似于HttpRequest.responseText 的东西,以至于我完全忽略了 HttpClientResponse 是一个流。不过,快速的第二个问题是,您是否有任何理由使用 StringBuffer 和 StreamTransformer 而不是解码来自 BytesBuilder 的结果?
    • 没有具体原因。我刚刚改进了文档中的示例:api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/…。也许您可以使用 BytesBuilder 获得更好的性能
    • 这太令人困惑了,我从这个例子开始,也从文档中找到的其他例子开始。我充其量只能使用 Future 对象,我无法将其超出范围变成一个简单的 String var。我能够阅读.then((String body) =&gt; print(body) 中的响应正文。但我不能在该范围之外传递该内容。 ``` String _get_response_body(String url) sync* { String out; http.get(url).then((response) { print(" status: ${response.statusCode}"); print(" body: ${response.body}"); out = readResponse(response); }) ;退出; }
    • 我要导入什么包?我导入了dart:convert,但它不起作用
    • 仅仅读取 Http 响应的正文怎么会这么难看?飞镖太糟糕了。
    【解决方案2】:

    低级

    这里是收集响应流的await for 版本。它比使用完成器更紧凑。

    Future<String> readResponse(HttpClientResponse response) async {
      final contents = StringBuffer();
      await for (var data in response.transform(utf8.decoder)) {
        contents.write(data);
      }
      return contents.toString();
    }
    

    您应该将其包装在 try catch 块中以处理错误。

    高级

    大多数情况下,您会在客户端使用 http 库:

    // import 'package:http/http.dart';
    
    Response response = await get(url);
    String content = response.body;
    

    更多详情请见this article

    【讨论】:

      【解决方案3】:

      HttpClientResponse 获取正文的一种简单方法是:

      Future<String> readResponse(HttpClientResponse response) async {
        return response.transform(utf8.decoder).join();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-20
        • 1970-01-01
        • 2019-07-07
        • 1970-01-01
        相关资源
        最近更新 更多