post传值单个多个参数 400错误 解决方案

post传值单个多个参数 400错误 解决方案

先说直接操作,再来分析,最后补充springboot的传递参数注解。【穿插一下背景:前端使用vue,后端使用springboot 】

  • 第一种:传递单个参数,修改请求
    headers[‘content-type’]=‘application/x-www-form-urlencoded’

  • 第二种:传递多个参数,
    1.修改请求头headers[‘content-type’]=‘application/json’
    2.转换传递参数JSON.stringify()
    我的是这样

	let data={
			   	  icon:val.icon,
				  name:val.name,
				  buyNum:val.buyNum,
				  price:val.price,
				  mid:val.id
			     }
			data=JSON.stringify(data)
			const res=await this.$api.menu.addMenuApi(data) 

3.最后一步,修改后端接口参数 @RequestBody String xxxx。如果写成@RequestBody Menu menu 对象格式会报错。
在这里插入图片描述
---------------------------完结------------------------------
注意的几个点:
1.http协议中get无需请求头,post需要。
post请求单个参数对应请求头为
headers[‘content-type’]=‘application/x-www-form-urlencoded’

post请求多个参数对应请求头为
headers[‘content-type’]=‘application/json’ 同时,要把传入的参数转换格式JSON.stringify(),后端需要使用(@RequestBody String xxx)String格式来接收

2.在springboot中的传值约定
单个参数使用 @RequestParam
多个参数使用 @RequestBody

<think>嗯,用户问的是如何在Spring Boot中使用@PostMapping接收两个实体类,并且前端用Vue和JS。首先,我需要回忆一下Spring MVC的参数绑定机制。通常,控制器方法参数如果是实体类,默认是通过请求参数(可能是表单数据或JSON)绑定的。但如果有多个实体参数,可能需要考虑参数是如何从前端递过来的。 用户提供的例子是public AjaxResult register(LoginBody loginBody, InfoFarm infoFarm),这里有两个对象。默认情况下,Spring会尝试将请求参数分别绑定到这两个对象的属性上。不过,如果前端递的参数名有冲突,比如两个实体类都有同名的属性,这可能会导致问题。或者,如果参数是嵌套的,可能需要用不同的策略。 接下来,前端使用Vue和JavaScript。通常,前端发送POST请求时,数据可以是表单数据或者JSON。如果是表单数据,参数需要扁平化,比如loginBody.username和infoFarm.farmName,这样后端才能正确绑定到对应的对象属性。或者,如果前端发送的是JSON,那么结构可能需要包含两个对象的键,比如{ loginBody: {...}, infoFarm: {...} },但这时候后端需要用@RequestBody来接收一个包含这两个对象的大对象,而不能直接作为方法参数的两个独立对象。 这里可能存在误解,用户可能希望在不修改后端代码的情况下,直接两个对象。但根据Spring MVC的处理方式,当方法参数多个对象时,会尝试将请求参数绑定到这些对象的属性中,而不是通过JSON结构。因此,正确的做法可能是让前端将参数平铺,或者使用一个包装类来包含这两个对象,然后在后端用@RequestBody接收这个包装类。 不过用户已经写好了方法参数是两个实体类,所以可能需要调整前端的参方式。比如,使用表单数据,并且参数名加上前缀,如loginBody.username和infoFarm.name。这样Spring会自动将参数映射到对应的对象属性。或者,如果前端用JSON,可能需要后端使用@RequestParam或者@ModelAttribute,但这两个注解通常用于单个对象。 另一个可能性是,用户的前端发送的是JSON数据,结构是一个包含两个对象的大对象,这时候后端需要用@RequestBody来接收一个包含这两个对象属性的DTO,而不是分开的两个参数。因此,可能需要调整后端参数接收方式,或者让前端调整参结构。 总结下来,正确的做法可能是让前端将参数平铺,并添加前缀,或者后端使用一个包装类来接收这两个对象。需要详细解释这两种方法,并给出示例代码,包括前端如何构造请求体和后端如何接收。</think>在Spring Boot中使用`@PostMapping`接收两个实体类时,需要注意参数绑定规则,结合Vue.js前端的常见方式,以下是解决方案和示例: --- ### **1. 后端代码(Spring Boot)** #### **方案一:平铺参数 + `@ModelAttribute`(推荐表单提交)** ```java @PostMapping("/register") public AjaxResult register( @ModelAttribute LoginBody loginBody, @ModelAttribute InfoFarm infoFarm ) { // 业务逻辑 } ``` - **参数规则**:前端需将`loginBody`和`infoFarm`的属性平铺参,例如: ```json { "username": "test", "password": "123", "farmName": "My Farm", "farmAddress": "xxx" } ``` - **要求**:`LoginBody`和`InfoFarm`的属性名不能冲突,否则Spring无法区分归属。 --- #### **方案二:JSON嵌套对象 + 包装类(推荐RESTful API)** 1. **创建包装类**: ```java @Data public class RegisterRequest { private LoginBody loginBody; private InfoFarm infoFarm; } ``` 2. **修改Controller**: ```java @PostMapping("/register") public AjaxResult register(@RequestBody RegisterRequest request) { LoginBody loginBody = request.getLoginBody(); InfoFarm infoFarm = request.getInfoFarm(); // 业务逻辑 } ``` --- ### **2. 前端代码(Vue.js + Axios)** #### **方案一对应参(表单格式)** ```javascript axios.post('/register', { username: 'test', password: '123', farmName: 'My Farm', farmAddress: 'xxx' }, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); ``` --- #### **方案二对应参(JSON格式)** ```javascript axios.post('/register', { loginBody: { username: 'test', password: '123' }, infoFarm: { farmName: 'My Farm', farmAddress: 'xxx' } }, { headers: { 'Content-Type': 'application/json' } }); ``` --- ### **3. 关键注意事项** 1. **`@ModelAttribute` vs `@RequestBody`**: - `@ModelAttribute`:接收 **表单数据或URL参数**(格式如`key1=value1&key2=value2`)。 - `@RequestBody`:接收 **JSON格式数据**,需要明确指定请求头`Content- 如果`LoginBody`和`InfoFarm`有同名属性(如都包含`id`),平铺参会导致数据错乱,建议使用方案二。 3. **Content-Type**: - 表单提交时,使用`application/x-www-form-urlencoded`。 - JSON提交时,使用`application/json`。 --- ### **完整示例代码** #### **后端包装类 + `@RequestBody`** ```java @Data public class RegisterRequest { private LoginBody loginBody; private InfoFarm infoFarm; } @PostMapping("/register") public AjaxResult register(@RequestBody RegisterRequest request) { // 使用 request.getLoginBody() 和 request.getInfoFarm() } ``` #### **前端Vue.js调用** ```javascript axios.post('/register', { loginBody: { username: 'test', password: '123' }, infoFarm: { farmName: 'My Farm', address: 'xxx' } }).then(response => { console.log(response.data); }); ``` --- 选择方案时,优先根据接口设计风格(表单提交 vs RESTful JSON)决定。推荐使用方案二(JSON嵌套对象),结构更清晰且可扩展性更强。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值