flutter - 'Response<dynamic>'实例flutter Api消费

标签 flutter chopper

我正在尝试使用 chopper 在 flutter 中发出发布请求。我制作了一个 ApiService.dart 文件作为 生成器文件。

import 'package:bindle/Chopper/Models/LoginResponse.dart';
import 'package:chopper/chopper.dart';
part 'ApiService.chopper.dart';

@ChopperApi(baseUrl: 'http://192.168.1.20/bindal/api/v1/user/')
abstract class ApiService extends ChopperService {

  @Post(path: "login")
  Future<Response<LoginResponse>> doLogin([
  @Header('auth_key') String authType,
  @Query('email') String email,
  @Query('password') String password,
  @Query('userType') String userType,
  ]);

  static ApiService create() {
  final client = ChopperClient(
   // The first part of the URL is now here
   baseUrl: 'http://192.168.1.20/bindal/api/v1/user/',
   services: [
     // The generated implementation
     _$ApiService(),
   ],
   interceptors: [
    HttpLoggingInterceptor()
   ],
    // Converts data to & from JSON and adds the application/json header.
    converter: JsonConverter(),
  );

  // The generated class with the ChopperClient passed in
  return _$ApiService(client);
 }
}

这是我生成的文件。

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'ApiService.dart';

// **************************************************************************
// ChopperGenerator
// **************************************************************************

class _$ApiService extends ApiService {
 _$ApiService([ChopperClient client]) {
 if (client == null) return;
 this.client = client;
}

final definitionType = ApiService;

Future<Response<LoginResponse>> doLogin(
   [String authType, String email, String password, String userType]) {
  final $url = 'http://192.168.1.20/bindal/api/v1/user/login';
  final Map<String, dynamic> $params = {
  'email': email,
  'password': password,
  'userType': userType
 };
 final $headers = {'auth_key': authType};
 final $request = Request('POST', $url, client.baseUrl,
    parameters: $params, headers: $headers);
return client.send<LoginResponse, LoginResponse>($request);
 }
}

接下来我要做的是生成一个名为 LoginResponse 的模型类,我必须在其中获取数据。

abstract class LoginResponse implements Built<LoginResponse, LoginResponseBuilder> {

int get status;
String get message;

LoginResponse._();

factory LoginResponse([void Function(LoginResponseBuilder) updates]) = _$LoginResponse;
static LoginResponse fromJson(String jsonString){
return serializers.deserializeWith(LoginResponse.serializer, json.decode(jsonString));
}
 static Serializer<LoginResponse> get serializer => _$loginResponseSerializer; 
 }

这是使用 built_value 生成器为上述 LoginResponse.dart 文件生成的文件

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'LoginResponse.dart';

// **************************************************************************
// BuiltValueGenerator
// **************************************************************************

Serializer<LoginResponse> _$loginResponseSerializer =
 new _$LoginResponseSerializer();

class _$LoginResponseSerializer implements StructuredSerializer<LoginResponse> {
@override
final Iterable<Type> types = const [LoginResponse, _$LoginResponse];
@override
final String wireName = 'LoginResponse';

@override
Iterable<Object> serialize(Serializers serializers, LoginResponse object,
   {FullType specifiedType = FullType.unspecified}) {
   final result = <Object>[
   'status',
   serializers.serialize(object.status, specifiedType: const FullType(int)),
   'message',
   serializers.serialize(object.message,
       specifiedType: const FullType(String)),
  ];

 return result;
 }

 @override
 LoginResponse deserialize(
    Serializers serializers, Iterable<Object> serialized,
    {FullType specifiedType = FullType.unspecified}) {
    final result = new LoginResponseBuilder();

   final iterator = serialized.iterator;
   while (iterator.moveNext()) {
   final key = iterator.current as String;
   iterator.moveNext();
   final dynamic value = iterator.current;
   switch (key) {
     case 'status':
       result.status = serializers.deserialize(value,
           specifiedType: const FullType(int)) as int;
       break;

    case 'message':
       result.message = serializers.deserialize(value,
           specifiedType: const FullType(String)) as String;
       break;
   }
 }

 return result.build();
  }
 }

 class _$LoginResponse extends LoginResponse {
@override
final int status;
@override
final String message;

factory _$LoginResponse([void Function(LoginResponseBuilder) updates]) =>
   (new LoginResponseBuilder()..update(updates)).build();

_$LoginResponse._({this.status, this.message}) : super._() {
 if (status == null) {
   throw new BuiltValueNullFieldError('LoginResponse', 'status');
 }
 if (message == null) {
   throw new BuiltValueNullFieldError('LoginResponse', 'message');
   }
  }

 @override
 LoginResponse rebuild(void Function(LoginResponseBuilder) updates) =>
   (toBuilder()..update(updates)).build();

  @override
 LoginResponseBuilder toBuilder() => new LoginResponseBuilder()..replace(this);

@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is LoginResponse &&
    status == other.status &&
    message == other.message;

  @override
 int get hashCode {
  return $jf($jc($jc(0, status.hashCode), message.hashCode));
 }

  @override
  String toString() {
  return (newBuiltValueToStringHelper('LoginResponse')
      ..add('status', status)
      ..add('message', message))
    .toString();
   }
  }

  class LoginResponseBuilder
   implements Builder<LoginResponse, LoginResponseBuilder> {
   _$LoginResponse _$v;

  int _status;
  int get status => _$this._status;
  set status(int status) => _$this._status = status;

  String _message;
  String get message => _$this._message;
  set message(String message) => _$this._message = message;

 LoginResponseBuilder();

  LoginResponseBuilder get _$this {
 if (_$v != null) {
   _status = _$v.status;
   _message = _$v.message;
   _$v = null;
  }
  return this;
 }

  @override
  void replace(LoginResponse other) {
   if (other == null) {
    throw new ArgumentError.notNull('other');
   }
   _$v = other as _$LoginResponse;
 }

  @override
  void update(void Function(LoginResponseBuilder) updates) {
   if (updates != null) updates(this);
  }

  @override
  _$LoginResponse build() {
   final _$result =
      _$v ?? new _$LoginResponse._(status: status, message: message);
   replace(_$result);
   return _$result;
 }
 }

最后我在登录页面调用了我的api

  void doLogin(String email, String pass, BuildContext context) async {
  try {
   final response = await Provider.of<ApiService>(context)
  .doLogin("d1d2fe0514f7d5c748c0e7e085b36f74","arpit1692@gmail.com",
  "e10adc3949ba59abbe56e057f20f883e","App");
   print(response.body);
  } catch (e) {
    print(e);
  }
 }

这最终给了我 Exception as => 'Response dynamic' 的实例

请帮助我纠正我做错的地方。

最佳答案

响应返回 dyanmic 的原因是因为响应没有序列化到您定义的模型。如果 LoginResponse 是应该用于响应的模型,则 LoginResponse 类应该有 fromJson() 应该序列化 json 响应。可以关注这个guide帮助您管理 json 序列化。

关于flutter - 'Response<dynamic>'实例flutter Api消费,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61652259/

相关文章:

flutter - MobX 中 ObservableList 和 @observable List 有什么不同

android - 您需要使用 Facebook 设置登录才能访问 API

flutter 工具栏在状态栏下方重叠

ios - flutter app 没有占用 ipad 屏幕的全宽?

android - 如何为图标勾勒颜色,但您也可以填充颜色 [Flutter]

flutter - 坏状态 : Unexpected diagnostics: after flutter upgrade to 1. 20.1

php - Flutter + Chopper POST API 无法在网络中运行

api - Flutter Chopper 401 更新和重试拦截器