Flutter技术入门与实战
上QQ阅读APP看书,第一时间看更新

2.6 Http请求

HTTP协议通常用于做前后端的数据交互。Flutter请求网络有两种方法,一种是用Http请求,另一种是用HttpClient请求。

1.Http请求方式

在使用Http方式请求网络时,需要导入http包。如下所示:

        import 'package:http/http.dart' as http;

请看下面的完整示例代码,示例中发起了一个http的get请求,并将返回的结果信息打印到控制台里:

        import 'package:flutter/material.dart';
        import 'package:http/http.dart' as http;
        void main() => runApp(new MyApp());
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return new MaterialApp(
              title: 'http请求示例’,
              home: new Scaffold(
                appBar: new AppBar(
                  title: new Text('http请求示例’),
                ),
                body: new Center(
                  child: new RaisedButton(
                    onPressed: () {
                      var url = 'http://httpbin.org/';
                      //http://httpbin.org/发送get请求
                      http.get(url).then((response) {
                        print("状态:${response.
                          statusCode}");
                        print("正文:${response.body}");
                      });
                    },
                    child: new Text(’发起http请求’),
                  ),
                ),
              ),
            );
          }
        }

请求界面如图2-8所示。

图2-8 Http请求示例效果图

点击“发起http请求”按钮,程序开始请求指定的url,如果服务器正常返回数据,则状态码为200。控制台输出内容如下:

        Performing hot reload...
        Syncing files to device iPhone X...
        Reloaded 1 of 509 libraries in 452ms.
        flutter:状态:200
        flutter:正文:<! DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>httpbin.org</title>
            <link href="https://fonts.googleapis.com/css? family=Open+Sans:400,700|Source
              +Code+Pro:300,600|Titillium+Web:400,600,700"
                rel="stylesheet">
            <link rel="stylesheet" type="text/css" href="/flasgger_static/swagger-ui.
              css">
            <link rel="icon" type="image/png" href="/static/favicon.ico" sizes="64x64
              32x32 16x16" />
            <style>
                html {
                    box-sizing: border-box;
                    overflow: -moz-scrollbars-vertical;
                    overflow-y: scroll;
                }
                *,
                *:before,
                *:after {
                    box-sizing: inherit;
                }
                body {
                    margin: 0;
                    background: #fafafa;
                }
            </style>
        </head>

注意

服务器返回状态200,同时返回正文。完整的正文远不只这些内容,你可以自己测试此示例,并查看控制台的输出消息。

2.HttpClient请求方式

在使用HttpClient方式请求网络时,需要导入io及convert包,如下所示:

        import 'dart:convert';
        import 'dart:io';

请看下面的完整示例代码,示例中使用HttpClient请求了一条天气数据,并将返回的结果信息打印到控制台里。具体请求步骤看代码注释即可。

        import 'package:flutter/material.dart';
        import 'dart:convert';
    import 'dart:io';
    void main() => runApp(MyApp());
    class MyApp extends StatelessWidget {
      //获取天气数据
      void getWeatherData() async {
        try {
          //实例化一个HttpClient对象
          HttpClient httpClient = new HttpClient();
          //发起请求
          HttpClientRequest request = await httpClient.getUrl(
              Uri.parse("http://t.weather.sojson.com/api/weather/city/101030100"));
          //等待服务器返回数据
          HttpClientResponse response = await request.close();
          //使用utf8.decoderresponse里解析数据
          var result = await response.transform(utf8.decoder).join();
          //输出响应头
          print(result);
          //httpClient关闭
          httpClient.close();
        } catch (e) {
          print("请求失败:$e");
        } finally {
        }
      }
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'httpclient请求’,
          home: Scaffold(
            appBar: AppBar(
              title: Text('httpclient请求’),
            ),
            body: Center(
              child: RaisedButton(
                child: Text("获取天气数据"),
                onPressed: getWeatherData,
              ),
            ),
          ),
        );
          }
        }

请求界面如图2-9所示。

图2-9 HttpClient请求示例效果图

点击“获取天气数据”按钮,程序开始请求指定的url,如果服务器正常返回数据,则状态码为200。控制台输出内容如下:

        Performing hot reload...
        Syncing files to device iPhone X...
        Reloaded 1 of 419 libraries in 412ms.
        flutter:  {"time":"2018-11-30  08:09:00", "cityInfo":{"city":"天津市", "cityId":
    "101030100", "parent":"天津", "updateTime":"07:56"}, "date":"20181130", "message":
    "Success! ",  "status":200, "data":{"shidu":"84%", "pm25":30.0, "pm10":79.0, "quality":"
    ", "wendu":"1", "ganmao":"极少数敏感人群应减少户外活动", "yesterday":{"date":"29日星期四
    ", "sunrise":"07:08", "high":"高温 9.0", "low":"低温 0.0", "sunset":"16:50", "aqi":86.
    0, "fx":"东风", "fl":"<3", "type":"", "notice":"愿你拥有比阳光明媚的心情"}, "forecast":
    [{"date":"30日星期五", "sunrise":"07:09", "high":"高温 10.0", "low":"低温 1.0", "sunse
    t":"16:50", "aqi":53.0, "fx":"西风", "fl":"<3", "type":"", "notice":"愿你拥有比阳光明媚
    的心情"}, {"date":"01日星期六", "sunrise":"07:10", "high":"高温 10.0", "low":"低温4.0",
    "sunset":"16:49", "aqi":94.0, "fx":"东风", "fl":"<3", "type":"", "notice":"不要被阴云
    遮挡住好心情"}, {"date":"02日星期日", "sunrise":"07:11", "high":"高温 1<>

注意

返回的数据是JSON格式,所以后续还需要做JSON处理。另外还需要使用utf8. decoder从response里解析数据。

如果请求里需要带参数,可以在URI里增加查询参数,具体的请求地址和参数要根据实际需要编写,代码如下所示:

        Uri uri=Uri(scheme: "https", host: "t.weather.sojson.com", queryParameters: {
            "_id": 26,
            "city_code": "101030100", //接口需要的city_code
            "city_name": "天津"
          });