flutter - 如何将 JSON-LD 转换为飞镖对象
问题描述
我将 Symfony API 平台和 Flutter 用于 Web 项目。Api 返回 JSON-LD 格式,如下所示:
但我收到了这个错误:
对于颤振项目,我遵循了文档https://flutter.dev/docs/cookbook/networking/fetch-data:
课本:
class Book {
final int id;
final String isbn;
final String title;
Book({this.id, this.isbn, this.title});
factory Book.fromJson(Map<String, dynamic> json) {
return Book(
id: json['id'] as int,
isbn: json['isbn'] as String,
title: json['title'] as String,
);
}
}
这是book_http_service.dart :
class BookHttpService {
Future<Book> listBooks() async {
final response = await http.get('http://192.168.1.13:8000/api/books');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Book.fromJson(json.decode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load books');
}
}
}
这是显示书籍的界面(book_list.dart)
class _BookState extends State<BookList> {
final BookHttpService bookHttpService = BookHttpService();
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder<Book>(
future: bookHttpService.listBooks(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error.toString()}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
);
}
}
解决方案
您可以在下面复制粘贴运行完整代码
您可以在完整代码中查看Book
类
第 1 步:假设您的 json 字符串如下所示
String jsonString = '''
{
"@context": "api/contexts/Book",
"@id":"api/books",
"@type":"hydra:Collection",
"hydra:member":[
{
"@id": "api/books/2",
"@type": "Book",
"id":2,
"isbn":"8545",
"title":"test body",
"author":"abc",
"pubLicationDate":"2020-01-14T16:29:16+01:00",
"active":false,
"owner":null
},
{
"@id": "api/books/2",
"@type": "Book",
"id":1,
"isbn":"1234",
"title":"test body 2",
"author":"def",
"pubLicationDate":"2020-01-14T16:29:16+01:00",
"active":false,
"owner":null
}
]
}
''';
第 2 步:解析bookFromJson(response.body);
第 3 步:显示数据ListView
FutureBuilder<Book>(
future: _future,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: snapshot.data.hydraMember.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
child: Center(
child:
Text('${snapshot.data.hydraMember[index].title}'))
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
Book bookFromJson(String str) => Book.fromJson(json.decode(str));
String bookToJson(Book data) => json.encode(data.toJson());
class Book {
String context;
String id;
String type;
List<HydraMember> hydraMember;
Book({
this.context,
this.id,
this.type,
this.hydraMember,
});
factory Book.fromJson(Map<String, dynamic> json) => Book(
context: json["@context"],
id: json["@id"],
type: json["@type"],
hydraMember: List<HydraMember>.from(
json["hydra:member"].map((x) => HydraMember.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"@context": context,
"@id": id,
"@type": type,
"hydra:member": List<dynamic>.from(hydraMember.map((x) => x.toJson())),
};
}
class HydraMember {
String id;
String type;
int hydraMemberId;
String isbn;
String title;
String author;
DateTime pubLicationDate;
bool active;
dynamic owner;
HydraMember({
this.id,
this.type,
this.hydraMemberId,
this.isbn,
this.title,
this.author,
this.pubLicationDate,
this.active,
this.owner,
});
factory HydraMember.fromJson(Map<String, dynamic> json) => HydraMember(
id: json["@id"],
type: json["@type"],
hydraMemberId: json["id"],
isbn: json["isbn"],
title: json["title"],
author: json["author"],
pubLicationDate: DateTime.parse(json["pubLicationDate"]),
active: json["active"],
owner: json["owner"],
);
Map<String, dynamic> toJson() => {
"@id": id,
"@type": type,
"id": hydraMemberId,
"isbn": isbn,
"title": title,
"author": author,
"pubLicationDate": pubLicationDate.toIso8601String(),
"active": active,
"owner": owner,
};
}
class BookHttpService {
Future<Book> listBooks() async {
//final response = await http.get('http://192.168.1.13:8000/api/books');
String jsonString = '''
{
"@context": "api/contexts/Book",
"@id":"api/books",
"@type":"hydra:Collection",
"hydra:member":[
{
"@id": "api/books/2",
"@type": "Book",
"id":2,
"isbn":"8545",
"title":"test body",
"author":"abc",
"pubLicationDate":"2020-01-14T16:29:16+01:00",
"active":false,
"owner":null
},
{
"@id": "api/books/2",
"@type": "Book",
"id":1,
"isbn":"1234",
"title":"test body 2",
"author":"def",
"pubLicationDate":"2020-01-14T16:29:16+01:00",
"active":false,
"owner":null
}
]
}
''';
final response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return bookFromJson(response.body);
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load books');
}
}
}
class BookList extends StatefulWidget {
@override
_BookListState createState() => _BookListState();
}
class _BookListState extends State<BookList> {
Future _future;
final BookHttpService bookHttpService = BookHttpService();
@override
void initState() {
_future = bookHttpService.listBooks();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Test'),
),
body: Container(
child: FutureBuilder<Book>(
future: _future,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: snapshot.data.hydraMember.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
child: Center(
child:
Text('${snapshot.data.hydraMember[index].title}')),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error.toString()}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: BookList(),
);
}
}
推荐阅读
- parsing - 用转义的单引号解析字符串
- css - 为什么“input-group-append”不覆盖其父高度?
- c++ - std::bitset 是否有 ffs() 等价物?
- javascript - Highlight.js 不尊重子模式的父正则表达式
- ios - 如何使用 Swift 动态设置 UIView 高度
- java - 即使 IAM 存在,配置文件也不能为空错误 AWS ~ java sdk
- acumatica - 如何将多个网格/表格/DAC 绑定到一个标题
- android - 为什么我的第一个 Retrofit 调用不起作用,但下一个调用完美?
- python-3.x - 如何同时运行多个python脚本?
- python-3.x - 在 Python 中,有没有办法使用 networkx 以标准格式显示神经网络?