flutter에 있는 json의 객체 목록을 역직렬화하는 방법
json serialization에는 dart 패키지 json_serializable을 사용하고 있습니다.플래터 매뉴얼을 보면 다음과 같이 단일 개체를 역직렬화하는 방법이 나와 있습니다.
Future<Post> fetchPost() async {
final response =
await http.get('https://jsonplaceholder.typicode.com/posts/1');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
단, 다트는 단일 인스턴스가 아닌 항목 목록에 대해 동일한 작업을 수행하는 방법을 이해할 수 없을 정도로 익숙하지 않습니다.
대응 기구가 지도이거나 그에 따라 지도 목록을 처리하는 서비스입니다.당신이 가지고 있는 코드로 계산하면 당신은 1개의 아이템을 계산하고 있습니다.
응답 본문이 반복할 수 있는 경우, 내가 당신의 질문을 올바르게 이해하고 있다면 그에 따라 해석하고 걸어야 합니다.
예:
Iterable l = json.decode(response.body);
List<Post> posts = List<Post>.from(l.map((model)=> Post.fromJson(model)));
여기서 post는 투고 목록입니다.
편집: 여기에 명료한 메모를 추가하고 싶습니다.여기서의 목적은 반환된 응답을 디코딩하는 것입니다.다음 단계에서는 JSON 오브젝트의 반복 가능한 인스턴스를 오브젝트의 인스턴스로 변환합니다.이는 클래스 내에서 JSON 메서드를 생성하여 적절하게 JSON을 구현함으로써 이루어집니다.다음으로 구현 예를 제시하겠습니다.
class Post {
// Other functions and properties relevant to the class
// ......
/// Json is a Map<dynamic,dynamic> if i recall correctly.
static fromJson(json): Post {
Post p = new Post()
p.name = ...
return p
}
}
나는 요즘 다트에서 좀 더 나은 유틸리티로 해야 할 일을 하는 것에 대해 추상적이다.구문이 조금 어긋난 것 같습니다만, 이것은 의사 코드입니다.
항상 문제없이 사용하고 있습니다.
List<MyModel> myModels;
var response = await http.get("myUrl");
myModels=(json.decode(response.body) as List).map((i) =>
MyModel.fromJson(i)).toList();
당신은 또한 그것을 할 수 있습니다.
List<dynamic> parsedListJson = jsonDecode("your json string");
List<Item> itemsList = List<Item>.from(parsedListJson.map<Item>((dynamic i) => Item.fromJson(i)));
서 ''는Item
이에서는, 「커스텀 클래스」를 .이 클래스에서는toJson
★★★★★★★★★★★★★★★★★」fromJson
.
자세한 설명을 위해 JSON 파싱의 또 다른 예를 제시하겠습니다.
예를 들어 JSON 오브젝트의 아이템 배열을 해석한다고 합시다.
factory YoutubeResponse.fromJSON(Map<String, dynamic> YoutubeResponseJson)
{
// Below 2 line code is parsing JSON Array of items in our JSON Object (YouttubeResponse)
var list = YoutubeResponseJson['items'] as List;
List<Item> itemsList = list.map((i) => Item.fromJSON(i)).toList();
return new YoutubeResponse(
kind: YoutubeResponseJson['kind'],
etag: YoutubeResponseJson['etag'],
nextPageToken: YoutubeResponseJson['nextPageToken'],
regionCode: YoutubeResponseJson['regionCode'],
mPageInfo: pageInfo.fromJSON(YoutubeResponseJson['pageInfo']),
// Here we are returning parsed JSON Array.
items: itemsList);
}
데이터와 저 같은 json이라고 하는 이름의 합니다).이 경우 다음 이름을 가진 클래스를 만듭니다(생성합니다.Img
:
import 'dart:convert';
Img imgFromJson(String str) => Img.fromJson(json.decode(str));
String imgToJson(Img data) => json.encode(data.toJson());
class Img {
String id;
String img;
dynamic decreption;
Img({
this.id,
this.img,
this.decreption,
});
factory Img.fromJson(Map<String, dynamic> json) => Img(
id: json["id"],
img: json["img"],
decreption: json["decreption"],
);
Map<String, dynamic> toJson() => {
"id": id,
"img": img,
"decreption": decreption,
};
}
추신. 앱을 사용할 수 있습니다.quicktype.io에서 json 데이터 클래스를 dart로 생성하고 게시물을 서버로 전송합니다.
Future<List<Img>> _getimages() async {
var response = await http.get("http://192.168.115.2/flutter/get_images.php");
var rb = response.body;
// store json data into list
var list = json.decode(rb) as List;
// iterate over the list and map each object in list to Img by calling Img.fromJson
List<Img> imgs = list.map((i)=>Img.fromJson(i)).toList();
print(imgs.runtimeType); //returns List<Img>
print(imgs[0].runtimeType); //returns Img
return imgs;
}
자세한 내용은 Flutter의 복잡한 JSON 구문 분석을 참조하십시오.
완전한 예
오브젝트 리스트의 JSON 시리얼화 및 역직렬화의 완전한 예를 다음에 나타냅니다.< Object >여기에는 네스트된 서브클래스와 리스트<서브>로 구성된 메인클래스가 있습니다.
Json 표본
{
"title": "something",
"sub": {"name": "a", "num": 0},
"sub_list": [
{"name": "b", "num": 1},
{"name": "c", "num": 2}
]
}
메인 클래스
class Main {
String title;
Sub sub;
List<Sub> subList;
Main(this.title, this.sub, this.subList);
Main.fromJson(Map<String, dynamic> json)
: title = json['title'],
sub = Sub.fromJson(json['sub']),
subList = List<dynamic>.from(json['sub_list'])
.map((i) => Sub.fromJson(i))
.toList();
Map<String, dynamic> toJson() => {
'title': title,
'sub': sub.toJson(),
'sub_list': subList.map((item) => item.toJson()).toList(),
};
}
서브클래스
class Sub {
String name;
int n;
Sub(this.name, this.n);
Sub.fromJson(Map<String, dynamic> json)
: name = json['name'],
n = json['n'];
Map<String, dynamic> toJson() => {
'name': name,
'n': n,
};
}
사용.
void main(List<String> args) {
var sub = Sub("a", 0);
print(sub.name); // a
Map<String, dynamic> jsonSub = {"name": "a", "n": 0};
var subFromJson = Sub.fromJson(jsonSub);
print(subFromJson.n); // 0
var main = Main("something", Sub("a", 0), [Sub("b", 1)]);
print(main.title); // something
print(main.sub.name); // a
print(main.subList[0].name); // b
var jsonMain = {
"title": "something",
"sub": {"name": "a", "n": 0},
"sub_list": [
{"name": "b", "n": 1},
{"name": "c", "n": 2}
]
};
var mainFromJson = Main.fromJson(jsonMain);
print(mainFromJson.title); // something
print(mainFromJson.sub.name); // a
print(mainFromJson.subList[0].name); // b
print(mainFromJson.subList[1].name); // c
}
하다
모델 클래스(LoginResponse)를 만듭니다.json을 dart로 변환하려면 여기를 클릭하십시오.
LoginResponce loginResponce=LoginResponce.fromJson(json.decode(response.body));
이제 모델(loginResponce)에서 데이터를 얻을 수 있습니다.
strong-mode를 유효하게 하면, 타입 정보가 없기 때문에, 상기의 솔루션은 실제로는 컴파일 되지 않습니다.
이것은 dart 2.14 시점에서 strong 모드가 유효하게 되어 컴파일 됩니다.
analysis_discl.discl
include: package:lints/recommended.yaml
analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false
import 'dart:convert';
// read the json file. This example use dcli but you just
// need [source] to contain the json string.
var source = dcli.read(_failedTrackerFilename).toParagraph();
var l = json.decode(source) as Iterable;
var failures = List<UnitTest>.from(l.map<UnitTest>(
(dynamic i) => UnitTest.fromJson(i as Map<String, dynamic>)));
모델 클래스입니다.
class SuggestedMovie {
String title;
String genres;
int movieId;
SuggestedMovie({this.title, this.genres, this.movieId});
factory SuggestedMovie.fromJson(Map<dynamic, dynamic> parsedJson) {
return SuggestedMovie(
movieId: parsedJson['movieId'],
title: parsedJson['title'] as String,
genres: parsedJson['genres'] as String,
);
}
}
다음 코드는 JSON 응답을 목록으로 역직렬화하는 코드입니다.
suggestedMovie = (json.decode(jsonResponse.data) as List)
.map((i) => SuggestedMovie.fromJson(i))
.toList();
flutter에 있는 json의 객체 목록을 역직렬화하는 방법
역직렬화JSONSerializer
.
코드 생성 예:
import 'dart:io';
import 'package:object_serializer/json_serializer_generator.dart';
import 'package:yaml/yaml.dart';
void main() {
final classes = loadYaml(_classes) as Map;
final g = JsonSerializerGenerator();
final classesCode = g.generateClasses(classes);
final values = {
'classes': classesCode,
};
var source = g.render(_template, values);
source = g.format(source);
File('bin/stackoverflow.dart').writeAsStringSync(source);
}
const _classes = '''
Post:
fields:
userId: int
id: int
title: String
body: String
''';
const _template = r'''
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() async {
final res1 =
await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
final post = Post.fromJson(jsonDecode(res1.body) as Map);
print(post.title);
final res2 =
await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
final posts = Post.fromJsonList(jsonDecode(res2.body) as List);
print('Posts: ${posts.length}');
if (posts.isNotEmpty) {
print(posts.first.title);
}
}
{{classes}}
''';
생성된 예의 소스 코드:
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() async {
final res1 =
await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
final post = Post.fromJson(jsonDecode(res1.body) as Map);
print(post.title);
final res2 =
await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
final posts = Post.fromJsonList(jsonDecode(res2.body) as List);
print('Posts: ${posts.length}');
if (posts.isNotEmpty) {
print(posts.first.title);
}
}
class Post {
Post(
{required this.userId,
required this.id,
required this.title,
required this.body});
factory Post.fromJson(Map json) {
return Post(
userId: json['userId'] == null ? 0 : json['userId'] as int,
id: json['id'] == null ? 0 : json['id'] as int,
title: json['title'] == null ? '' : json['title'] as String,
body: json['body'] == null ? '' : json['body'] as String,
);
}
final int userId;
final int id;
final String title;
final String body;
static List<Post> fromJsonList(List json) {
return json.map((e) => Post.fromJson(e as Map)).toList();
}
Map<String, dynamic> toJson() {
return {
'userId': userId,
'id': id,
'title': title,
'body': body,
};
}
static List<Map<String, dynamic>> toJsonList(List<Post> list) {
return list.map((e) => e.toJson()).toList();
}
}
때때로 JSON의 구조와 Pojo 클래스에 문제가 발생합니다.
JSON은 다음과 같습니다.
{"records":[{"name":"noor ","email":"email","mobileNo":187,"feedback":"good"}]}
이 JSON에 따르면 올바른 방법으로 pojo 클래스를 만들어야 합니다.JSON을 붙여넣으면 다음 사이트에서 pojo 클래스가 제공됩니다.https://javiercbk.github.io/json_to_dart/
거기에 클래스 이름을 붙여야 합니다.질문의 이름과 함께 위의 JSON에 따라 다음 두 가지 pojo 클래스를 찾았습니다.
class Questions {
List<Records>? records;
Questions({this.records});
Questions.fromJson(Map<String, dynamic> json) {
if (json['records'] != null) {
records = <Records>[];
json['records'].forEach((v) {
records!.add(new Records.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.records != null) {
data['records'] = this.records!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Records {
String? name;
String? email;
int? mobileNo;
String? feedback;
Records({this.name, this.email, this.mobileNo, this.feedback});
Records.fromJson(Map<String, dynamic> json) {
name = json['name'];
email = json['email'];
mobileNo = json['mobileNo'];
feedback = json['feedback'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['email'] = this.email;
data['mobileNo'] = this.mobileNo;
data['feedback'] = this.feedback;
return data;
}
}
여기서 중요한 것은 레코드를 목록으로 변환하는 것입니다.전화는 다음과 같습니다.
Future<List<Records>> getRecordList() async {
return await http.get(Uri.parse(URL)).then((response) {
print(response.body.toString());
Questions questions = Questions.fromJson(json.decode(response.body));
print(questions.records![0].feedback);
List<Records> list_s = [];
for (int i = 0; i < questions.records!.length; i++) {
list_s.add(questions.records![i]);
}
print(list_s[0].name);
return list_s;
});
}
}
마지막으로 UI 부분은 다음과 같습니다.
class _FeedbackListPageState extends State<FeedbackListPage> {
List<Records> list_s = [];
@override
void initState() {
super.initState();
FormController().getRecordList().then((value) {
setState(() {
list_s = value;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: darkGreen,
elevation: 0.0,
titleSpacing: 10.0,
title: Text(widget.title),
centerTitle: true,
leading: InkWell(
onTap: () {
Navigator.pop(context);
},
child: const Icon(
Icons.arrow_back_ios,
color: Colors.black54,
),
),
),
body: ListView.builder(
itemCount: list_s.length,
itemBuilder: (context, index) {
return ListTile(
title: Row(
children: <Widget>[
Icon(Icons.person),
Expanded(
child: Text("${list_s[index].name} (${list_s[index].email})"),
)
],
),
subtitle: Row(
children: <Widget>[
Icon(Icons.message),
Expanded(
child: Text(list_s[index].feedback.toString()),
)
],
),
);
},
),
);
}
}
이 문제를 해결하기 위해 제가 한 일은 다음과 같습니다.
List<YourItemClass> items = [];
final data = jsonDecode(resp.body); //Here it goes your json array
for (dynamic item in data) {
items.add(YourItemClass.fromMap(item));
}
return items;
물론, 당신은 그것을 가질 필요가 있다.fromMap()
에 있어서의 방법.YourItemClass
그렇지 않으면 quicktype.io에서 클래스의 단일 json 인스턴스를 붙여넣을 수 있습니다(및 dart 언어를 선택합니다).
언급URL : https://stackoverflow.com/questions/51053954/how-to-deserialize-a-list-of-objects-from-json-in-flutter
'source' 카테고리의 다른 글
react에서 함수를 트리거하기 전에 setState가 완료될 때까지 어떻게 기다려야 합니까? (0) | 2023.03.05 |
---|---|
PHP, WordPress에 로그인하기 위한 cURL 게시 (0) | 2023.03.05 |
React는 라벨 요소의 'for' 속성을 무시합니다. (0) | 2023.02.28 |
Angular JS : 공장 출하시 $http 서비스 (0) | 2023.02.28 |
React 구성 요소 업데이트(매초) (0) | 2023.02.28 |