Flutter通过参数调用API报错400:请求数据问题排查
代码中的错误分析及修正方案
核心错误(直接导致400 Bad Request的原因)
- URL参数拼接存在语法错误:请求URL中混入了无关的HTML标签(
<span class="math-inline">、</span>),同时字符串插值语法错误:- 错误示例:
TotalRooms=<span class="math-inline">totalroom、OccupiedRooms=</span>{OccupiedRoom.toStringAsFixed(2)} - 正确写法:使用Dart标准的字符串插值语法
$变量名或${表达式},并移除所有无关HTML标签。
- 错误示例:
- 传递格式化后的字符串而非原始数值:
roomRevenue和TotalRevenue是经formatter.format()处理后的带格式字符串(可能包含逗号、货币符号等),后端无法将这类字符串解析为数字类型,触发参数校验失败。- 例如
formatter.format(1234)可能输出"1,234",后端无法识别为有效数字。
- 例如
其他逻辑/语法问题
- 嵌套函数定义不合理:将
submitform()函数定义在setState()回调内部,逻辑混乱且可能引发上下文相关问题,建议移到setState外部或直接内联请求逻辑。 - POST请求参数放置不符合规范:虽然URL传参可行,但POST请求通常将参数放在请求体(body)中,而非URL查询参数,更符合RESTful规范且避免URL过长问题。
- 冗余类型转换:多处存在不必要的类型转换,比如
double.parse(((OccupiedRoom/totalroom)*100).toStringAsFixed(2)),可直接计算后保留小数,无需转字符串再转回double。
修正后的代码示例
// 将提交函数移到setState外部 Future<void> submitForm(String hotel, String date, int totalroom, double occupiedRoom, double adr, double occRate, double totalRoomRevenue, double revPAR, int fnbRevenue, double rawTotalRevenue) async { print('ready'); // 构建正确的URL参数,移除HTML标签,使用标准插值语法 final uri = Uri.parse( 'http://xxxx/xxxx/api/hotel/InsertHotelDailyRevenue' '?hotel=$hotel' '&RptDate=$date' '&TotalRooms=$totalroom' '&OccupiedRooms=${occupiedRoom.toStringAsFixed(2)}' '&OccupancyRate=${occRate.toStringAsFixed(2)}' '&ADR=${adr.toStringAsFixed(2)}' '&RevPAR=${revPAR.toStringAsFixed(2)}' '&TotalRoomRevenue=$totalRoomRevenue' '&TotalFnBRevenue=$fnbRevenue' '&TotalRevenue=$rawTotalRevenue' ); final response = await http.post( uri, headers: <String, String>{ 'Content-Type': 'application/x-www-form-urlencoded', }, ); print('after api'); if (response.statusCode == 201) { print('201'); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Data submitted successfully!')), ); } else { String errorMessage = 'Failed to submit data.'; switch (response.statusCode) { case 400: errorMessage = 'Bad request. Please check the submitted data.'; break; case 401: errorMessage = 'Unauthorized. Please check your credentials.'; break; case 403: errorMessage = 'Forbidden. You are not authorized to submit data.'; break; default: errorMessage = 'Error: ${response.statusCode}'; } throw Exception(errorMessage); } } // 原setState逻辑修正 setState(() { String OccRoomText = _occRoomController.text; String ADRText = _adrController.text; String FnBRevenueText = _fnbrevenueController.text; String extraRevenueText = _extrarevenueController.text; if (_formKey.currentState!.validate()) { print('2'); String hotel = 'DTH'; String date = _dateController.text; int totalroom = 299; double OccupiedRoom = double.parse(OccRoomText); double ADR = double.parse(ADRText); double FnBRevenue = double.parse(FnBRevenueText); double ExtraRevenue = double.parse(extraRevenueText); // 简化计算,移除冗余类型转换 occRate = ((OccupiedRoom/totalroom)*100); TotalRoomRevenue = OccupiedRoom * ADR; RevPAR = TotalRoomRevenue / totalroom; TotalFnBRevenue = FnBRevenue + ExtraRevenue; int FNBRevenue = TotalFnBRevenue.round(); final rawTotalRevenue = TotalRoomRevenue + FNBRevenue; // 格式化仅用于前端展示,不传给后端 roomRevenue = formatter.format(TotalRoomRevenue.round()); TotalRevenue = formatter.format(rawTotalRevenue.round()); print(TotalRevenue); // 调用外部提交函数 submitForm( hotel, date, totalroom, OccupiedRoom, ADR, occRate, TotalRoomRevenue, RevPAR, FNBRevenue, rawTotalRevenue ).then((_) { print('请求成功'); }).catchError((error) { print(error); }); } });
内容的提问来源于stack exchange,提问作者unknown
相关产品推荐
相关产品推荐

