Flutter Serverpod 0.9.21示例项目调用接口返回400无错误信息问题
Serverpod 0.9.21自定义接口返回400错误排查与解决
问题背景
- 基于Serverpod 0.9.21搭建后端,已将Flutter客户端地址改为
http://10.0.2.2:8080/,解决模拟器SocketException问题,示例say hello功能正常 - 自定义
addProvince接口返回400错误,无errorMessage,数据库province表已创建且状态正常
已完成的配置与代码
1. Province协议定义(test_server包内)
class: Province table: province fields: name: String isEnabled: bool
2. ProvinceEndpoint实现
import 'package:serverpod/serverpod.dart'; import '../generated/protocol.dart'; class ProvinceEndpoint extends Endpoint { Future<bool> addProvince(Session session, Province province) async { await Province.insert(session, province); return true; } }
3. 客户端main.dart代码
import 'package:back_client/back_client.dart'; import 'package:flutter/material.dart'; import 'package:serverpod_flutter/serverpod_flutter.dart'; var client = Client('http://10.0.2.2:8080/') ..connectivityMonitor = FlutterConnectivityMonitor(); void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { final _nameController = TextEditingController(text: "name1"); String result = "here"; addProvince() async { final province = Province(name: _nameController.text, isEnabled: true); client.province.addProvince(province).then((value) { if (value) { setState(() { result = "Done adding ${_nameController.text} province"; }); } else { result = "Nashod!"; } }).catchError((onError) { final error = (onError is ServerpodClientException) ? "${onError.message} ${onError.statusCode}" : "Error "; setState(() { result = error; }); }).whenComplete(() { print("done"); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Column( children: [ TextField( controller: _nameController, ), Text( result, style: Theme.of(context).textTheme.headline3, ) ], ), floatingActionButton: FloatingActionButton( onPressed: addProvinces, // 存在方法名拼写错误 child: const Icon(Icons.add), ), ); } }
排查与解决步骤
修正客户端方法名拼写错误
客户端代码中FloatingActionButton的onPressed绑定的是addProvinces,但实际定义的方法是addProvince(多了末尾的s),修正为onPressed: addProvince,确保点击按钮能正确触发接口调用。查看Serverpod服务端日志
400错误的详细原因通常会输出在Serverpod的控制台日志中,重点关注:- 协议序列化/反序列化失败提示
- 数据库插入时的约束错误(比如字段非空但传入空值)
- Endpoint未正确注册的提示
检查协议字段可空性
若数据库表要求name字段非空,需在协议中明确标记字段为必填:fields: name: String, required isEnabled: bool, required修改后重新执行
serverpod generate并重启服务。验证接口请求结构
使用Postman或curl直接调用接口http://10.0.2.2:8080/api/province/addProvince,传入标准JSON参数:{ "province": { "name": "test_province", "isEnabled": true } }根据返回的详细错误信息定位问题。
重新生成代码并重启服务
确保serverpod generate执行无报错,生成的protocol.dart包含完整的Province类与客户端方法,之后重启Serverpod服务器避免缓存影响。
内容的提问来源于stack exchange,提问作者Kamran Akbary
相关产品推荐
相关产品推荐

