Flutter restheart oid 映射

Posted

技术标签:

【中文标题】Flutter restheart oid 映射【英文标题】:Flutter restheart oid mapping 【发布时间】:2022-01-13 16:45:06 【问题描述】:

使用flutter dio和retrofit我遇到了restheart API的问题。

如何正确映射 mongodb oid?

我有一个这样的 main.dart:

import 'dart:convert';
import 'package:dio/dio.dart';
import 'dart:developer';

import 'package:retrofit_experiment/utils/rest_client.dart';

var auth = 'Basic ' + base64Encode(utf8.encode('admin:secret'));

Future<void> main(List<String> args) async 
  final dio = Dio(); // Provide a dio instance
  dio.options.headers["authorization"] = auth;

  final client = RestClient(dio);

  final json = await client.getUser("61a94d306c573846b4c0f8bf");

  log(
    'User with id 61a94d306c573846b4c0f8bf',
    name: 'getUser',
    error: jsonEncode(json),
  );

  client.getUser("61a94d306c573846b4c0f8bf").then((it) => print(it.id));


一个rest_client.dart:

import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';

import 'package:retrofit_experiment/model/user.dart';

part 'rest_client.g.dart';

@RestApi(baseUrl: "http://localhost:8080")
abstract class RestClient 
  factory RestClient(Dio dio, String baseUrl) = _RestClient;

  @GET("/users/id")
  Future<User> getUser(@Path("id") String id);

生成:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'rest_client.dart';

// **************************************************************************
// RetrofitGenerator
// **************************************************************************

class _RestClient implements RestClient 
  _RestClient(this._dio, this.baseUrl) 
    baseUrl ??= 'http://localhost:8080';
  

  final Dio _dio;

  String? baseUrl;

  @override
  Future<User> getUser(id) async 
    const _extra = <String, dynamic>;
    final queryParameters = <String, dynamic>;
    final _data = <String, dynamic>;
    final _result = await _dio.fetch<Map<String, dynamic>>(_setStreamType<User>(
        Options(method: 'GET', headers: <String, dynamic>, extra: _extra)
            .compose(_dio.options, '/users/$id',
                queryParameters: queryParameters, data: _data)
            .copyWith(baseUrl: baseUrl ?? _dio.options.baseUrl)));
    final value = User.fromJson(_result.data!);
    return value;
  

  RequestOptions _setStreamType<T>(RequestOptions requestOptions) 
    if (T != dynamic &&
        !(requestOptions.responseType == ResponseType.bytes ||
            requestOptions.responseType == ResponseType.stream)) 
      if (T == String) 
        requestOptions.responseType = ResponseType.plain;
       else 
        requestOptions.responseType = ResponseType.json;
      
    
    return requestOptions;
  

还有这个 user.dart:

import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';

@JsonSerializable()
class User 
  @JsonKey(name: '_id.\$oid')
  String? id;
  @JsonKey(name: 'first_name')
  String? firstName;
  @JsonKey(name: 'last_name')
  String? lastName;
  String? avatar;
  String? email;

  User(this.id, this.firstName, this.lastName, this.avatar, this.email);

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

生成:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

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

User _$UserFromJson(Map<String, dynamic> json) 
  return User(
    id: json[r'_id.$oid'] as String?,
    firstName: json['first_name'] as String?,
    lastName: json['last_name'] as String?,
    avatar: json['avatar'] as String?,
    email: json['email'] as String?,
  );


Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>
      r'_id.$oid': instance.id,
      'first_name': instance.firstName,
      'last_name': instance.lastName,
      'avatar': instance.avatar,
      'email': instance.email,
    ;

我得到这样的响应数据:

"_id.$oid":null,"first_name":"Emma","last_name":"…faces/3-image.jpg","email":"emma.wong@reqres.in"

一切都被正确映射,但不是 oid。 我做错了什么?

【问题讨论】:

【参考方案1】:

我不熟悉 Dart,但我怀疑错误是您试图将 _id 作为字符串获取,而它是 ObjectId。

RESTHeart 使用所谓的strict mode 表示 ObjectId


 "_id":  "$oid": "61a94d306c573846b4c0f8bf" 

您可能希望查看 https://github.com/mongo-dart/mongo_dart/issues/145 以获取有关如何从字符串表示解析 ObjectId 的示例。

【讨论】:

以上是关于Flutter restheart oid 映射的主要内容,如果未能解决你的问题,请参考以下文章

RESTheart安装与设置

Hibernate映射文件

Hibernate基础学习—对象-关系映射(上)

如何使用带有OID 1.3.6.1.4.1.50530.1.1的自定义X.509v3 corda扩展的openssl为corda建立网络映射证书

在 Grails 和 SpringSecurity 中访问 Oracle Internet Directory (OID) 中的嵌套 LDAP 角色

显示名称证书OID - Windows