Flutter 入门笔记(Part 7) 网络编程与JSON解析

1 . 网络编程与JSON解析

  • 默认的HttpClient请求网络
get() async {
  //创建网络调用示例,设置通用请求行为(超时时间)
  var httpClient = HttpClient();
  httpClient.idleTimeout = Duration(seconds: 5);

  //构造URI,设置user-agent为"Custom-UA"
  var uri = Uri.parse("https://flutter.dev");
  var request = await httpClient.getUrl(uri);
  request.headers.add("user-agent", "Custom-UA");

  //发起请求,等待响应
  var response = await request.close();

  //收到响应,打印结果
  if (response.statusCode == HttpStatus.ok) {
    print(await response.transform(utf8.decoder).join());
  } else {
    print('Error: \nHttp status ${response.statusCode}');
  }
}
  • 在 Flutter 中,所有网络编程框架都是以 Future 作为异步请求的包装
  • http是Dart官方的另一个网络请求类,需要添加依赖http: '>=0.11.3+12'
httpGet() async {
  //创建网络调用示例
  var client = http.Client();

  //构造URI
  var uri = Uri.parse("https://flutter.dev");

  //设置user-agent为"Custom-UA",随后立即发出请求
  http.Response response = await client.get(uri, headers : {"user-agent" : "Custom-UA"});

  //打印请求结果
  if(response.statusCode == HttpStatus.ok) {
    print(response.body);
  } else {
    print("Error: ${response.statusCode}");
  }
}
  • dio,一般使用这个,dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等...添加依赖dio: '>2.1.3'
void getRequest() async {
  //创建网络调用示例
  Dio dio = new Dio();

  //设置URI及请求user-agent后发起请求
  var response = await dio.get("https://flutter.dev", options:Options(headers: {"user-agent" : "Custom-UA"}));

 //打印请求结果
  if(response.statusCode == HttpStatus.ok) {
    print(response.data.toString());
  } else {
    print("Error: ${response.statusCode}");
  }
}

//下载-------------

//使用FormData表单构建待上传文件
FormData formData = FormData.from({
  "file1": UploadFileInfo(File("./file1.txt"), "file1.txt"),
  "file2": UploadFileInfo(File("./file2.txt"), "file1.txt"),

});
//通过post方法发送至服务端
var responseY = await dio.post("https://xxx.com/upload", data: formData);
print(responseY.toString());

//使用download方法下载文件
dio.download("https://xxx.com/file1", "xx1.zip");

//增加下载进度回调函数
dio.download("https://xxx.com/file1", "xx2.zip", onReceiveProgress: (count, total) {
  //do something      
});


//并行请求--------------

//同时发起两个并行请求
List<Response> responseX= await Future.wait([dio.get("https://flutter.dev"),dio.get("https://pub.dev/packages/dio")]);

//打印请求1响应结果
print("Response1: ${responseX[0].toString()}");
//打印请求2响应结果
print("Response2: ${responseX[1].toString()}");

//拦截器-----------------

//增加拦截器
dio.interceptors.add(InterceptorsWrapper(
    onRequest: (RequestOptions options){
      //为每个请求头都增加user-agent
      options.headers["user-agent"] = "Custom-UA";
      //检查是否有token,没有则直接报错
      if(options.headers['token'] == null) {
        return dio.reject("Error:请先登录");
      } 
      //检查缓存是否有数据
      if(options.uri == Uri.parse('http://xxx.com/file1')) {
        return dio.resolve("返回缓存数据");
      }
      //放行请求
      return options;
    }
));

//增加try catch,防止请求报错
try {
  var response = await dio.get("https://xxx.com/xxx.zip");
  print(response.data.toString());
}catch(e) {
  print(e);
}

2 . JSON解析

  • 只能手动解析.
import 'dart:convert';

String jsonString = '''
{
  "id":"123",
  "name":"张三",
  "score" : 95,
  "teacher": { "name": "李四", "age" : 40 }
}
''';

//json解析

//所谓手动解析,是指使用 dart:convert 库中内置的 JSON 解码器,将 JSON 字符串解析成自定义对象的过程。

class Teacher {
  String name;
  int age;

  Teacher({this.name, this.age});

  factory Teacher.fromJson(Map<String, dynamic> parsedJson) {
    return Teacher(name: parsedJson['name'], age: parsedJson['age']);
  }

  @override
  String toString() {
    return 'Teacher{name: $name, age: $age}';
  }
}

class Student {
  String id;
  String name;
  int score;
  Teacher teacher;

  Student({this.id, this.name, this.score, this.teacher});

  //从Map中取
  factory Student.fromJson(Map<String, dynamic> parsedJson) {
    return Student(
        id: parsedJson['id'],
        name: parsedJson['name'],
        score: parsedJson['score'],
        teacher: Teacher.fromJson(parsedJson['teacher']));
  }

  @override
  String toString() {
    return 'Student{id: $id, name: $name, score: $score, teacher: $teacher}';
  }
}


void main() {

  final jsonResponse = json.decode(jsonString);//将字符串解码成Map对象
  Student student = Student.fromJson(jsonResponse);//手动解析
  print(student.teacher.name);
}
  • json解析比较耗时,放compute中去进行,不用担心阻塞UI了. compute得有Widget才行.

手机扫码阅读