如何向REST API批量提交数据?解决旧数据被覆盖问题
问题描述
尝试向REST API一次性提交数据列表时,API会删除之前的数据并仅保存新数据。
提供的JSON数据示例:
[ { "name": "6E72Ln9Y095x8n80Xgk6/435291346914161.jpg", "class": "APKZZX", "email": "2142103j983H1", "roll_number": "6E72Ln9Y095x8n80Xgk6", "password": "2023-02-27 21:25:50.347756", "image": "", "role": "student", "school_id": "2142103j983H1", "id": "734506" }, { "name": "6E72Ln9Y095x8n80Xgk6/435291346914161.jpg", "class": "APKZZX", "email": "2142103j983H1", "roll_number": "6E72Ln9Y095x8n80Xgk6", "password": "2023-02-27 21:25:50.347756", "image": "", "role": "student", "school_id": "2142103j983H1", "id": "734506" } ]
当前Flutter代码:
upload() async { try { final prefs = await SharedPreferences.getInstance(); String? schoolId = prefs.getString('school_id'); var map = {}; List maps = List.empty(growable: true); Users user = Users(); var value = data.skip(1).toList(); for (var i = 0; i < value.length; i++) { user = Users( name: value[i][0].toString(), class1: value[i][1].toString(), email: value[i][2].toString(), roll_number: value[i][3].toString(), password: value[i][4].toString(), image: '', role: 'student', school_id: schoolId.toString(), id: randomAlphaNumeric(6), ); } value.forEach((element) { Db.post('users', user.toJson()); }); print(user.toJson().toString()); EasyLoading.showSuccess(user.toJson().toString()); } catch (e) { EasyLoading.showError('Khalad ayaa jira fadlan hubi oo ku celi'); } }
需求:实现向API一次性批量提交多条数据,或逐个提交数据。
代码问题分析
- 循环创建
user实例时,每次都会覆盖之前的变量,最终user仅保留最后一条用户数据 forEach循环中重复提交同一个用户数据,未实现多用户提交逻辑
解决方案
方案一:逐个提交数据
可以选择串行提交(等待前一个完成再提交下一个)或并行提交(同时发起所有请求):
串行提交(避免并发过高)
upload() async { try { final prefs = await SharedPreferences.getInstance(); String? schoolId = prefs.getString('school_id'); var value = data.skip(1).toList(); for (var i = 0; i < value.length; i++) { final user = Users( name: value[i][0].toString(), class1: value[i][1].toString(), email: value[i][2].toString(), roll_number: value[i][3].toString(), password: value[i][4].toString(), image: '', role: 'student', school_id: schoolId.toString(), id: randomAlphaNumeric(6), ); // 等待当前请求完成再执行下一个 await Db.post('users', user.toJson()); print('已提交第 ${i+1} 个用户'); } EasyLoading.showSuccess('所有用户提交完成'); } catch (e) { EasyLoading.showError('提交失败:${e.toString()}'); } }
并行提交(效率更高)
upload() async { try { final prefs = await SharedPreferences.getInstance(); String? schoolId = prefs.getString('school_id'); var value = data.skip(1).toList(); List<Future> submitFutures = []; for (var i = 0; i < value.length; i++) { final user = Users( name: value[i][0].toString(), class1: value[i][1].toString(), email: value[i][2].toString(), roll_number: value[i][3].toString(), password: value[i][4].toString(), image: '', role: 'student', school_id: schoolId.toString(), id: randomAlphaNumeric(6), ); submitFutures.add(Db.post('users', user.toJson())); } // 等待所有提交请求完成 await Future.wait(submitFutures); EasyLoading.showSuccess('所有用户提交完成'); } catch (e) { EasyLoading.showError('提交失败:${e.toString()}'); } }
方案二:批量提交数据
如果后端API支持接收数组格式的请求体(且逻辑为追加数据而非覆盖),可以一次性提交整个用户列表:
upload() async { try { final prefs = await SharedPreferences.getInstance(); String? schoolId = prefs.getString('school_id'); var value = data.skip(1).toList(); // 构建完整用户列表 List<Map<String, dynamic>> userList = []; for (var i = 0; i < value.length; i++) { final user = Users( name: value[i][0].toString(), class1: value[i][1].toString(), email: value[i][2].toString(), roll_number: value[i][3].toString(), password: value[i][4].toString(), image: '', role: 'student', school_id: schoolId.toString(), id: randomAlphaNumeric(6), ); userList.add(user.toJson()); } // 提交整个列表,注意接口路径需对应后端批量接口 await Db.post('users/batch', userList); EasyLoading.showSuccess('批量提交成功'); } catch (e) { EasyLoading.showError('批量提交失败:${e.toString()}'); } }
额外注意事项
由于class是Dart关键字,你的Users类用class1作为属性是正确的,但需要确保后端能识别该字段。可以通过JsonKey注解将class1映射为JSON里的class字段:
class Users { // ...其他属性 @JsonKey(name: 'class') final String class1; // 构造函数、toJson等逻辑 }
内容的提问来源于stack exchange,提问作者abdifatah nour
相关产品推荐
相关产品推荐

