Flutter使用Dio发送Multipart请求报错:后端缺失complaintData
问题排查与修复方案
核心问题分析
后端抛出MissingServletRequestPartException: Required part 'complaintData' is not present,主要有两个原因:
- 字段名拼写错误:FormData中
"images:"多了一个冒号,干扰了Multipart请求的字段解析逻辑,导致后端无法正确识别所有请求部分。 - JSON数据未序列化:直接将Map类型的
complaintData放入FormData,Spring Boot无法自动解析这种嵌套结构,需要先将Map转为JSON字符串。
修复后的代码
import 'dart:convert'; // 需导入json编码工具 Future<int> saveComplaint({ required String complaintSubject, required String complaintDescription, required String complaintPriority, required String categoryToken, required int pinCode, required String address, required String wardNo, required int contactNo, }) async { try { String? accessToken = await _secureStorage.readAccessToken(); String? userToken = await _secureStorage.readUserToken(); Options options = Options( validateStatus: (_) => true, contentType: Headers.multipartFormDataContentType, responseType: ResponseType.json, headers: {HttpHeaders.authorizationHeader: bearerPrefix + accessToken!}, ); List<dio.MultipartFile> files=[]; for (int i = 0; i < images.length; i++) { XFile image = images[i]; files.add(await dio.MultipartFile.fromFile( image.path, filename: 'image_$i.jpg', )); } Map<String, dynamic> complaintData = { 'complaintSubject': complaintSubject, 'complaintDescription': complaintDescription, 'complaintPriority': complaintPriority, 'categoryToken': categoryToken, 'pincode': pinCode.toString(), 'address': address, 'wardNo': wardNo, 'contactNo': contactNo.toString(), 'userToken': userToken ?? '', }; // 1. 将complaintData序列化为JSON字符串 String complaintJson = jsonEncode(complaintData); // 2. 修正images字段名的冒号问题 dio.FormData formData=dio.FormData.fromMap({ "complaintData": complaintJson, "images": files }); dio.Response response = await _dio.post(saveComplaintUrl, data: formData,options: options); log('Response data: ${response.data}'); Map<String, dynamic> responseData = response.data; if(responseData.isNotEmpty){ return responseData['code']; } } catch (err) { log('$err'); debugPrintStack(); } return -1; }
额外注意事项
- 确保Spring Boot后端接口中,
complaintData参数类型为String,接收后再反序列化为对应实体类。 - 若后端期望直接接收实体类类型的
complaintData,也可以尝试将Map拆分为FormData的平级字段,但JSON字符串的方式兼容性更强,更贴近Postman的请求格式。
内容的提问来源于stack exchange,提问作者ayush
相关产品推荐
相关产品推荐

