You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中GetConnect/GetX未调用后端且返回null对象问题

问题描述

使用GetX 4.6.5实现登录接口调用,按以下步骤实现后,控制台输出flutter: {jwt: null},且本地localhost:1337服务未被调用:

  1. 定义Provider类:
class CredentialsProvider extends GetConnect implements GetxService {
  @override
  void onInit() {
    httpClient.defaultDecoder =
        (val) => Auth.fromJson(val as Map<String, dynamic>);
    httpClient.baseUrl = 'http://localhost:1337/api/';
    super.onInit();
  }
  Future<Response<dynamic>> postCredentials(Credentials credentials) async {
    return await post('auth/local', credentials);
  }
}
  1. 在Binding类中添加依赖:
class LoginBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut(() => CredentialsProvider());
    Get.lazyPut(() => LoginController());
  }
}
  1. 注册LoginView路由:
GetPage(
  name: "/login",
  page: () => const LoginView(),
  binding: LoginBinding(),
)
  1. 在控制器中添加Provider:
class LoginController extends GetxController {
  final provider = Get.put(CredentialsProvider());
//...
}
  1. LoginView使用该控制器:
class LoginView extends GetView<LoginController> {...}
  1. 在LoginView的MaterialButton的onPressed中调用接口并打印结果:
onPressed: () {
  var c = Credentials(
      identifier: controller.emailController.text,
      password: controller.passwordController.text);
 controller.provider.postCredentials(c).then((value) {
    var auth = value.body as Auth;
    print(auth.toJson());
  });
},
  1. 通过GetX CLI生成Auth模型:
class Auth {
  String? jwt;
  User? user;

  Auth({this.jwt, this.user});

  Auth.fromJson(Map<String, dynamic> json) {
    jwt = json['jwt'];
    user = json['user'] != null ? User?.fromJson(json['user']) : null;
  }

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    data['jwt'] = jwt;
    if (user != null) {
      data['user'] = user?.toJson();
    }
    return data;
  }
}

class User {
  int? id;
  String? username;
  String? email;
  String? provider;
  bool? confirmed;
  bool? blocked;
  String? createdAt;
  String? updatedAt;

  User(
      {this.id,
      this.username,
      this.email,
      this.provider,
      this.confirmed,
      this.blocked,
      this.createdAt,
      this.updatedAt});

  User.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    username = json['username'];
    email = json['email'];
    provider = json['provider'];
    confirmed = json['confirmed'];
    blocked = json['blocked'];
    createdAt = json['createdAt'];
    updatedAt = json['updatedAt'];
  }

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    data['id'] = id;
    data['username'] = username;
    data['email'] = email;
    data['provider'] = provider;
    data['confirmed'] = confirmed;
    data['blocked'] = blocked;
    data['createdAt'] = createdAt;
    data['updatedAt'] = updatedAt;
    return data;
  }
}
解决方案

1. 修复重复初始化Provider的问题

在LoginBinding中已经通过Get.lazyPut注册了CredentialsProvider,但控制器里又调用Get.put创建了新实例,导致新实例的onInit未执行(baseUrl和defaultDecoder未配置),请求根本没有发送。

修改控制器代码,改用Get.find()获取已注册的实例:

class LoginController extends GetxController {
  final provider = Get.find<CredentialsProvider>();
  //...
}

2. 确保Credentials类实现toJson方法

GetConnect.post需要将请求对象序列化为JSON,若Credentials没有实现toJson,请求体为空会导致服务端无法处理,甚至请求发送失败。

补充Credentials类的序列化方法:

class Credentials {
  final String identifier;
  final String password;

  Credentials({required this.identifier, required this.password});

  Map<String, dynamic> toJson() {
    return {
      'identifier': identifier,
      'password': password,
    };
  }
}

3. 修复Auth模型的fromJson错误

原模型中User?.fromJson的多余问号会导致无法正确解析用户数据,修改为:

user = json['user'] != null ? User.fromJson(json['user']) : null;

4. 调整本地服务地址(模拟器环境)

Android模拟器无法直接通过localhost访问电脑本地服务,需替换为10.0.2.2;iOS模拟器可保留localhost或使用127.0.0.1。

修改Provider的baseUrl:

// Android模拟器
httpClient.baseUrl = 'http://10.0.2.2:1337/api/';
// iOS模拟器
// httpClient.baseUrl = 'http://localhost:1337/api/';

5. 添加错误日志排查

在请求回调中加入错误处理,方便定位问题:

controller.provider.postCredentials(c).then((value) {
  if (value.hasError) {
    print('请求状态码:${value.statusCode}');
    print('错误信息:${value.statusText}');
    print('错误详情:${value.error}');
  } else {
    var auth = value.body as Auth;
    print(auth.toJson());
  }
}).catchError((e) {
  print('捕获异常:$e');
});

内容的提问来源于stack exchange,提问作者Nima Mazloumi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:40:13