Flutter (twenty) - JSON parsing

Foreword

The previous Bowen has described in detail the development of a network request Flutter, but in fact most projects, the return HTML content is not enough, because most requested mobile terminal using a JSON data, so we need to know Flutter development, JSON knowledge resolved. (JSON (javaScript Object Notation, JS objects notation) is a lightweight data-interchange format)

Dart JSON an object is converted into

Suppose that we are developing now is a news App, then by accessing the relevant interface, such a simple server returns JSON data, as shown below:

{"title":"疫情疫苗出世,多板块重大利好"}

So how should we deal with this data is displayed on the screen it? I believe there have been Android Java development experience of the reader, must know how to restore this data into an object, and displayed in the interface. Similarly, in the Flutter development, you can put this data into JSON objects Dart, we first define the object Dart News, code is as follows:

class News{
  final String title;
  
  News({this.title});
  
  factory News.fromJson(Map<String,dynamic> json){
    return News(
      title: json['title'],
    );
  }
}

In dart: convert JSON inside a constant, which is returned from the server handles JSON data returned in response to a request by json.decode (response.body) method calls can result into JSON or city Map Type List Types of. If it is a JSON object returned will be a Map; if a JSON array is returned List.

The reason why the above code to map the value defined as dynamic, because not sure of the type of value, after all, there may be strings, there may be an integer, or use the automatic match type too.

practice

After JSON parsing, we need to show results in the form of interface to the user to see, so let directly to achieve its function:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState(news: httpPost());
}

class _MyHomePageState extends State<MyHomePage> {

  final Future<News> news;
  _MyHomePageState({Key key,this.news});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("HttpClient"),
      ),
      body:Center(
        child: FutureBuilder<News>(
          future: news,
          builder: (context,snapshot){
            if(snapshot.hasData){
              return Text(snapshot.data.title);
            }else if(snapshot.hasError){
              return Text("错误啦");
            }
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

Future<News> httpPost() async{
  final response=await http.get("http://liyuanjinglyj.com/demo/");
  if(response.statusCode==200){
    print(utf8.decode(response.bodyBytes));
    return News.fromJson(json.decode(response.body));
  }else{
    throw Exception('请求不到JSon');
  }

}

class News{
  final String title;

  News({this.title});

  factory News.fromJson(Map<String,dynamic> json){
    return News(
      title: json['title'],
    );
  }
}

Code is very simple, defined specifically herein Dart a class of JSON, JSON data for processing, while the components with FutureBuilder JSON displayed on the screen. First display shown in FIG.

The entity class generation tool JSON

The above can be said to generate static JSON format, that is manually define a JSON class, but if there are many, many data in JSON format, how to get JSON data it? A written affirmation of a very troublesome, so we need to use tools to automatically generate JSON class, here also need to import dependence in pubspec.yaml in:

dependencies:
  json_annotation: ^2.0.0

dev_dependencies:
  build_runner: ^1.0.0
  json_serializable: ^2.0.0

Then we create an entity class in the following format:

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User{
  String name;
  String email;
  User({this.name,this.email});

  factory User.fromJson(Map<String,dynamic> json)=>_$UserFromJson(json);

  Map<String,dynamic> toJson=>_$UserToJson(this);
}

Here will complain, especially part 'user.g.dart'; and the last two sentences, there will be a red wavy line prompt, but this is normal Do not worry, we can put the above code as a template, and then we project directory file, enter the following command:

flutter packages pub run build_runner build

After you have finished entering this command, it will generate a user.g.dart file in the same directory user.dart, as follows:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

User _$UserFromJson(Map<String, dynamic> json) {
  return User(name: json['name'] as String, email: json['email'] as String);
}

Map<String, dynamic> _$UserToJson(User instance) =>
    <String, dynamic>{'name': instance.name, 'email': instance.email};

For bloggers intuitive, so reducing the number of parameters, but in reality, JSON parameter will have many, and even level, so in this case, so that automatically generates up is certainly more convenient, but also more time-saving.

Enter effect

However, this approach also has a flaw, that is, if my JSON format is changed, it is also not the first time you build? Obviously, Flutter also take into account this situation, it is available to us a listening mode to achieve every generation, the command is as follows:

flutter packages pub run build_runner watch

This command only needs to be performed once, it will monitor has been running in the background, it can be automatically generated in what we do not operate.

When the server returns JSON class attributes are inconsistent properties

Although the above operation is very convenient, but also automatically generates problems to be solved, it is when your server returns JSON class and inconsistent field how to do? Of course, you can change the field directly, but may be a change will move the entire contents, so this time using annotations JsonKey way is more efficient, such as:

@JsonKey(name:'user_name')
final String userName;

Such notes plus automatic generation of JSON class is very perfect and efficient, can greatly improve the efficiency of the development process.

Published 109 original articles · won praise 141 · views 1 million +

Guess you like

Origin blog.csdn.net/liyuanjinglyj/article/details/104168589