使用Dio发起网络请求失败返回400错误码的问题求助
问题原因
你的代码存在4个核心问题,直接导致请求失败:
- 直接将Dart自定义实例作为
data参数传入Dio:Dio默认仅支持Map/List/String类型的请求体,你注释掉了wmsCoreMessage.toJson()的序列化步骤,传入自定义类时Dio无法正确生成符合要求的JSON结构,请求体格式完全不符合接口要求。 AuthToken实例未赋值硬编码必填参数:你用空构造方法创建了AuthToken对象,没有给接口要求的固定值(AuthKey、LoginTimeStamp、RequestNumber、UserID等)赋值,序列化后这些字段要么为null要么缺失,直接触发接口参数校验错误。EntityObject实例缺失必填字段:你初始化EntityObject时仅传入了邮箱和加密密码,漏了接口要求的ClientMAC、SessionIdentifier两个必填参数,参数不完整。- 缺少异常捕获和请求头显式配置:没有对请求异常做捕获处理,出错时无法定位具体错误原因;也没有显式指定
Content-Type: application/json请求头,部分服务端会因请求头不匹配拒绝请求。
正确实现方式
- 首先确保你的
AuthToken、EntityObject、WMSCoreMessage三个类的toJson()方法正确,输出的键名和接口要求完全一致(注意大小写敏感,比如接口键名是大驼峰MailID,如果你的类字段是小驼峰mailID,要在序列化时做字段名映射,不要直接用字段名作为JSON键)。 - 初始化模型时补全所有必填字段,不要留空。
- 请求时传入序列化后的Map作为请求体,显式指定请求头,加上异常捕获打印具体错误信息。
正确代码示例:
void userLogin() async { // 补全EntityObject所有必填字段 EntityObject eo = EntityObject( mailID: userName, passwordEncrypted: password, clientMAC: "02:00:00:00:00:00", // 可替换为动态获取的设备真实MAC sessionIdentifier: "192.168.1.186", // 可替换为动态获取的设备IP ); // 给AuthToken所有硬编码字段赋值 AuthToken ao = AuthToken( authKey: "FJ1189A002023", authToken: "", authValue: "", loginTimeStamp: "2022-06-07 10:08:15.316", // 需要动态生成的话可以用DateTime.now()按指定格式转字符串 requestNumber: 1, userID: "1", ); WMSCoreMessage wmsCoreMessage = WMSCoreMessage(entityObject: eo, authToken: ao); // 序列化对象为JSON Map,禁止直接传Dart自定义对象 final requestData = wmsCoreMessage.toJson(); var url = Apis.login2; // 显式配置Dio基础参数 final dio = Dio(BaseOptions( headers: { "Content-Type": "application/json", }, connectTimeout: const Duration(seconds: 10), receiveTimeout: const Duration(seconds: 10), )); try { Response response = await dio.post( url, data: requestData, ); print('请求成功,响应内容: $response'); // 在这里写后续响应处理逻辑 } on DioException catch (e) { // 打印具体错误信息方便定位 print('请求出错,状态码: ${e.response?.statusCode}'); print('错误响应内容: ${e.response?.data}'); print('错误信息: ${e.message}'); } catch (e) { print('其他异常: $e'); } }
额外排查点
如果改完还是报错,按以下顺序排查:
- 打印
requestData的完整内容,和接口给出的示例JSON逐字段对比,确保键名、大小写、值格式完全一致,没有缺字段、多字段。 - 确认接口请求方法确实为POST,没有额外的鉴权头、签名规则要求。
- 可以先用Postman等工具按示例参数调通接口,再把Postman生成的请求头、请求体和代码中的内容做对比,找出差异点。
内容的提问来源于stack exchange,提问作者Padmaja Rani
相关产品推荐
相关产品推荐

