Rust Actix-web POST JSON请求返回400 Bad Request问题排查
400错误核心原因
该错误是actix-web框架的JSON提取器反序列化请求体失败导致的,请求根本没进入你写的业务逻辑:你curl提交的JSON中id字段值为字符串类型"20",但Client结构体中id字段定义为i32整数类型,serde反序列化时类型不匹配直接抛出错误,框架自动返回400 Bad Request响应。
修复方案
- 最快修复方式:修改curl请求,将
id字段的字符串值改为数字类型,去掉外层双引号,修正后的命令如下:
curl -X POST -H "Content-Type: application/json" -d '{"id": 20, "first_name": "foo1", "last_name": "bar1", "address": "Bourghelles", "mail": "foo1@bar.com", "phone_number": "0620399062"}' http://127.0.0.1:8080/clients -v
- 如果需要兼容前端传字符串格式数字的场景,可以给结构体的
id字段添加serde配置,自动完成字符串到整数的转换(需要引入serde_with依赖),示例配置:
#[derive(Queryable, Insertable, Serialize, Deserialize)] pub struct Client { #[serde(deserialize_with = "serde_with::rust::deserialize_number_from_string")] pub id: i32, pub first_name: String, pub last_name: String, pub address: String, pub mail: String, pub phone_number: String, }
代码中其他需要修正的问题
- 连接池类型不匹配:你的handler函数中
pool参数标注为web::Data<SqlPool>(sqlx的连接池类型),但main函数中初始化的是diesel配套的r2d2 Mysql连接池,二者类型不一致会直接编译失败,请统一连接池类型。 - 业务逻辑错误:
create函数最后写死返回show(pool, 1),无论插入的记录id是多少,永远返回id=1的客户端数据,应该在插入完成后获取新记录的实际id,再查询对应记录返回。如果你的数据库id字段是自增属性,甚至不需要前端传id字段,直接由数据库生成即可。 - 冗余代码:
format!{"Hello world from create"};这行语句没有绑定变量也没有输出,属于无效代码,可以直接删除。
内容的提问来源于stack exchange,提问作者Valentin
相关产品推荐
相关产品推荐

