모든 모델 클래스에 JSON 시리얼라이저를 추가하시겠습니까?
Dart에서의 JSON 인코딩에 관한 한, Seth Ladd의 설명에 따르면 현재 최종적으로 승인된 공식 방법은 다음과 같습니다.dart:convert
+JSON.Encode
예를 들어 다음과 같은 모델 클래스(PODO)가 많이 있다고 합시다.
class Customer
{
int Id;
String Name;
}
도메인 오브젝트를 다음과 같이 JSON 인코딩할 수 있으면 좋겠습니다.
var customer = new Customer()
..Id = 17
..Name = "John";
var json = JSON.encode(customer);
불행히도, 이건 효과가 없을 거야...
Uncaught Error: Converting object to an encodable object failed.
Stack Trace:
#0 _JsonStringifier.stringifyValue (dart:convert/json.dart:416)
#1 _JsonStringifier.stringify (dart:convert/json.dart:336)
#2 JsonEncoder.convert (dart:convert/json.dart:177)
....
가 명시적으로 말하지 한...우리가 명시적으로 말하지 않는 한dart:convert
다음 중 하나:
class Customer
{
int Id;
String Name;
Map toJson() {
Map map = new Map();
map["Id"] = Id;
map["Name"] = Name;
return map;
}
}
ㅇㅇㅇㅇㅇㅇㅇㅇㅇ를 요?toJson
모든 모델 클래스에 적용하거나 더 나은 방법이 있을까요?
편집: 이것은 제가 찾고 있는 심플한 시리얼라이제이션입니다.
{
"Id": 17,
"Name": "John"
}
와 ToJson
ServiceStack에 있습니다.예를 들어 텍스트.
Dart의 시리얼라이제이션 라이브러리(아래 Matt B의 답변 참조)는 올바른 방향으로 나아가는 단계인 것 같습니다.하지만 이건...
var serialization = new Serialization()
..addRuleFor(Customer);
var json = JSON.encode(serialization.write(customer, format: new SimpleJsonFormat()));
...는 다음 값(키 없음)을 가진 배열만 생성합니다.
[17,"John"]
한편 기본 SimpleMapFormat을 사용하면 이 복잡한 표현이 생성됩니다.
아직 내가 찾던 걸 못 찾았어...
편집 2: 일부 컨텍스트 추가:저는 Dart에서 RESTful 웹 서비스를 구축하고 있으며, 다른 Dart 클라이언트뿐만 아니라 어떤 클라이언트에서도 쉽게 사용할 수 있는 JSON 시리얼화를 찾고 있습니다.예를 들어 이 질문에 대해 스택 Exchange API를 쿼리하면 이 JSON 응답이 생성됩니다.이것이 제가 찾고 있는 시리얼라이제이션 형식입니다.-아니면 Twitter REST API나 Facebook Graph API에서 반환되는 전형적인 JSON 응답을 보세요.
편집 3: 나는 이것에 대해 작은 블로그 투고를 썼다.해커 뉴스에 대한 설명도 참조하십시오.
IMO 이것은 Dart의 주요 결점이며, 웹 어플리케이션의 초점을 생각하면 놀라운 결과입니다.표준 라이브러리에서 JSON을 지원한다는 것은 JSON에서 또는 JSON에서 클래스를 시리얼화하는 것이 물처럼 기능한다는 것을 의미한다고 생각했지만 안타깝게도 JSON 지원은 불완전한 것 같습니다.이 경우 표준(PODO) 클래스를 구성하기 위해 느슨하게 타이핑된 맵을 사용하거나 불필요한 보일러 플레이트를 사용할 수 있습니다.예상대로 연재할 수 있습니다.
반사 및 미러 지원 없음
Flutter와 같은 인기 있는 Dart 플랫폼은 Reflection/Mirrors를 지원하지 않기 때문에 코드 생성 솔루션을 사용하는 방법밖에 없습니다.ServiceStack의 Dart 및 Flutter 기본 지원 방식을 사용하면 원격 URL에서 모든 ServiceStack 서비스에 대해 입력된 Dart 모델을 생성할 수 있습니다. 예:
$ npm install -g @servicestack/cli
$ dart-ref https://techstacks.io
위의 예에서는 의 Typeed API를 생성합니다.techstacks.io/types/dart 엔드포인트에서 생성된 DTO를 사용하여 NET TechStacks 프로젝트를 수행합니다.그러면 Dart의 JsonCodec 패턴에 따른 모델이 생성됩니다.이 패턴에서는 Dart 모델의 시리얼화를 커스터마이즈 할 수 있습니다.fromJson
컨스트럭터 및 " " " " " "toJson()
메서드에서는 .instance DTO의 예를 나타냅니다.
class UserInfo implements IConvertible
{
String userName;
String avatarUrl;
int stacksCount;
UserInfo({this.userName,this.avatarUrl,this.stacksCount});
UserInfo.fromJson(Map<String, dynamic> json) { fromMap(json); }
fromMap(Map<String, dynamic> json) {
userName = json['userName'];
avatarUrl = json['avatarUrl'];
stacksCount = json['stacksCount'];
return this;
}
Map<String, dynamic> toJson() => {
'userName': userName,
'avatarUrl': avatarUrl,
'stacksCount': stacksCount
};
TypeContext context = _ctx;
}
이 모델에서는 Dart의 기본 제공 json:convert API를 사용하여 모델을 JSON으로 직렬화 및 역직렬화할 수 있습니다. 예:
//Serialization
var dto = new UserInfo(userName:"foo",avatarUrl:profileUrl,stacksCount:10);
String jsonString = json.encode(dto);
//Deserialization
Map<String,dynamic> jsonObj = json.decode(jsonString);
var fromJson = new UserInfo.fromJson(jsonObj);
이 접근법의 장점은 Dart 2의 Strong Mode 유무에 관계없이 Flutter 및 AngularDart 또는 Dart Web Apps를 포함한 모든 Dart 플랫폼에서 작동한다는 것입니다.
생성된 DTO를 Serviceestack의 Dart 패키지와 함께 사용하면 엔드 투 엔드 타입의 솔루션을 사용할 수 있습니다.이 솔루션에서는, 타입이 끝난 DTO와의 사이에 JSON 시리얼화를 처리할 수 있습니다.다음은 예를 제시하겠습니다.
var client = new JsonServiceClient("https://www.techstacks.io");
var response = await client.get(new GetUserInfo(userName:"mythz"));
자세한 내용은 ServiceStack의 네이티브 Dart 지원에 대한 문서를 참조하십시오.
거울 달린 다트
Mirrors 지원을 이용할 수 있는 플랫폼에서 Dart를 사용하는 경우 Mixin을 사용하는 데 가장 적은 노력이 필요하다는 것을 알게 되었습니다. 예를 들어 다음과 같습니다.
import 'dart:convert';
import 'dart:mirrors';
abstract class Serializable {
Map toJson() {
Map map = new Map();
InstanceMirror im = reflect(this);
ClassMirror cm = im.type;
var decls = cm.declarations.values.where((dm) => dm is VariableMirror);
decls.forEach((dm) {
var key = MirrorSystem.getName(dm.simpleName);
var val = im.getField(dm.simpleName).reflectee;
map[key] = val;
});
return map;
}
}
PODO 클래스와 함께 사용할 수 있는 기능:
class Customer extends Object with Serializable
{
int Id;
String Name;
}
같이 쓸 수요.JSON.encode
:
var c = new Customer()..Id = 1..Name = "Foo";
print(JSON.encode(c));
결과:
{"Id":1,"Name":"Foo"}
주의: 미러 사용에 관한 주의사항을 참조하십시오.
맵이나 JSON으로 변환하는 등의 문제를 해결하기 위해 Exportable 라이브러리를 작성했습니다.이를 사용하면 모델 선언은 다음과 같습니다.
import 'package:exportable/exportable.dart';
class Customer extends Object with Exportable {
@export int id;
@export String name;
}
JSON으로 변환하려면 다음 작업을 수행합니다.
String jsonString = customer.toJson();
또한 JSON 문자열에서 새 개체를 쉽게 초기화할 수 있습니다.
Customer customer = new Customer()..initFromJson(jsonString);
또는 다음 중 하나:
Customer customer = new Exportable(Customer, jsonString);
상세한 것에 대하여는, README 를 참조해 주세요.
또는 Serialization 패키지를 사용하여 클래스에 규칙을 추가하는 방법도 있습니다.가장 기본적인 양식은 반사를 사용하여 속성을 자동으로 가져옵니다.
Redstone Mapper는 제가 사용한 것 중 최고의 연재 라이브러리입니다.JsonObject 및 Exportable에는 일부 클래스를 확장해야 하는 단점이 있습니다.Redstone Mapper를 사용하면 이런 구조를 만들 수 있습니다.
class News
{
@Field() String title;
@Field() String text;
@Field() List<FileDb> images;
@Field() String link;
}
및 setters와 되므로 getters에 주석을 달지 않고 수 .@Field()
필드 이름을 json에서 json으로 변경할 수 있습니다.네스트된 오브젝트가 있으면 서버와 클라이언트에서 동작합니다.Redstone Server MongoDB에 대해 설명하겠습니다.
내가 본 유일한 틀은 다트슨이지만 레드스톤 매퍼와 비교하면 아직 부족한 점이 있다.
해결 방법:
class Customer extends JsonObject
{
int Id;
String Name;
Address Addr;
}
class Address extends JsonObject{
String city;
String State;
String Street;
}
그러나 나의 목표는 모델 클래스에서 json으로 데이터를 바인드하는 것이다.이 솔루션은 모델 클래스를 수정할 수 있는 경우 작동하지만 반대로 모델 클래스를 변환하려면 솔루션 "외부"를 사용해야 합니다.
참고 항목: Dart에서 JsonObject 라이브러리를 사용한 JSON 목록 해석
이 문제를 해결하는 다른 패키지는 built_value입니다.
https://github.com/google/built_value.dart
built_value를 사용하면 모델 클래스는 다음과 같습니다.
abstract class Account implements Built<Account, AccountBuilder> {
static Serializer<Account> get serializer => _$accountSerializer;
int get id;
String get name;
BuiltMap<String, JsonObject> get keyValues;
factory Account([updates(AccountBuilder b)]) = _$Account;
Account._();
}
built_value는 단순히 시리얼라이제이션에 관한 것이 아니라 operator==, hashCode, toString 및 빌더 클래스도 제공합니다.
나는 이것으로 달성했습니다.
이 작업을 수행하려면 명시적으로 통과하십시오.ToJson: 클래스 선언 위의 @JsonSerialable() 주석에서 true입니다.User 클래스는 다음과 같이 표시됩니다.
import 'address.dart';
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable(explicitToJson: true)
class User {
String firstName;
Address address;
User(this.firstName, this.address);
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
https://flutter.dev/docs/development/data-and-backend/json#generating-code-for-nested-classes를 확인하십시오.
https://ashamp.github.io/jsonToDartModel/ 온라인 툴을 직접 사용하는 것을 선호합니다.
다음과 같은 기능이 있습니다.
- 온라인 사용, 플러그인 없음
- 지원 다차원 리스트
- 복합 json 지원
- support 모든 소품을 String type으로 변환
- 빈 소품 경고
- 1열 종렬
- dart 키워드 보호
- 인스턴트 컨버터
다른 도구보다 좋은 것 같아요.제안, 문제 또는 버그 보고가 있으시면 환영합니다.
일부 답변은 Flutter 2에 더 이상 적용되지 않습니다. 다음은 toJson 및 fromJson 메서드를 자동으로 생성하는 프로세스입니다.
https://syslog.dev/dev/development/data-and-syson/json#creating-model-the-json_creatible-way
PS: Asp에 있는 Newtonsoft 라이브러리를 사용하는 것처럼 간단했으면 합니다.이 솔루션은 자동화 솔루션에 가장 가깝습니다.
언급URL : https://stackoverflow.com/questions/20024298/add-json-serializer-to-every-model-class
'source' 카테고리의 다른 글
스프링 부트: java.lang.NoSch Method Error: javax.servlet.http.Http ServletRequest.getHttpServletMapping()Ljavax/servlet/http/HttpServletMapping; (0) | 2023.02.13 |
---|---|
WooCommerce - 다운로드 가능한 구매에 대한 배송 비활성화 (0) | 2023.02.13 |
Woocommerce에서 프로그래밍 방식으로 새 제품 특성 생성 (0) | 2023.02.13 |
JSON 형식을 모르는 Java에서의 JSON 해석 (0) | 2023.02.13 |
NSJONSerialization 사용방법 (0) | 2023.02.13 |