springBoot 与 axios 表单提交

本文探讨了Axios向SpringBoot应用提交表单数据时遇到的问题及解决方法,详细对比了不同配置下@ModelAttribute与@RequestBody的使用效果。

环境声明
springBoot : 1.8
java : jdk1.8
IDE : IDEA

问题描述
axios 表单提交,springBoot 无法接受到数据,但使用swagger测试,可以。

原因
1、axios的表单提交 ,content-type 默认为 application/json;charset=UTF-8
2、提交数据会附加在payload(以JSON形式)。
3、@ModelAttribute 可以接受表单的数据,但是content-type的类型需要为application/x-www-form。@RequestBody 可以接受表单数据,但是content-type类型需要为application/json。@RequestParam 从URL中接受请求参数。(不用于表单提交)。

实验

测试1.1(失败)

this.$axios({
    url:this.$rootPath+"/category/category",
    method:'post',
    data:{
      category:this.category
    }
  });
 public Object inserCategory(@ModelAttribute Category category) {}

http 状态码:

clipboard.png

请求成功,但是服务端没有接受到数据。原因是@ModelAttribute需要接收FormData形式的数据

测试1.2(失败)

this.$axios({
    url:this.$rootPath+"/category/category",
    method:'post',
    data:{
      category:this.category
    },
    headers:{
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  });
public Object inserCategory(@ModelAttribute Category category) {}

http状态码:

clipboard.png

Form Data 被默认组装成了 json的形式,虽然我们修改了Content-type。

测试1.3(失败)

if(valid) {
  this.$axios({
    url:this.$rootPath+"/category/category",
    method:'post',
    data:{
      name: this.category.name,
      desc: this.category.desc
    },
    headers:{
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  });
public Object inserCategory(@ModelAttribute Category category) {}

clipboard.png

FormData 还是json的形式, 不是以FormData的形式。服务端当然接受不到数据

测试1.4(成功)

if(valid) {
  this.$axios({
    url:this.$rootPath+"/category/category",
    method:'post',
    data:{
      name: this.category.name,
      desc: this.category.desc
    },
    headers:{
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    transformRequest: [function (data) {
      return that.$qs.stringify(data);
    }],
  });
 public Object inserCategory(@ModelAttribute Category category) {}

http状态码:

clipboard.png

使用qs对数据在提交前进行了格式化,将其转换成FormData的形式,此时服务端成功接收到数据
也就是说,使用@ModelAttribute修饰,客户端的content-type需要是 application/x-www-form-urlencoded 且 FormData数据是正确的FormData格式


测试@RequestBody:

测试2.1(失败)

if(valid) {
  this.$axios({
    url:this.$rootPath+"/category/category",
    method:'post',
    data:{
      name: this.category.name,
      desc: this.category.desc
    },
    headers:{
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    transformRequest: [function (data) {
      return that.$qs.stringify(data);
    }],
  });
 public Object inserCategory(@RequestBody Category category) {}

也就是说@RequstBody 只能支持以JSON数据格式上传。

测试2.2(失败)

this.$axios({
    url:this.$rootPath+"/category/category",
    method:'post',
    data:{
      category:this.category
    }
  })
public Object inserCategory(@RequestBody Category category) {}

以这种形式提交数据会失败,因为category在最外面又包装了一个对象。服务端无法正确解析。

测试2.3(成功)

this.$axios({
    url:this.$rootPath+"/category/category",
    method:'post',
    data:{
      name: this.category.name,
      desc: this.category.desc
    },
   });
public Object inserCategory(@RequestBody Category category) {}

以JSON的形式,将数据上传,服务端成功接受到数据

总结:@RequestBody 只能以json数据提交,数据会负载在Request Payload中;@ModelAttribute 可以以表单数据提交,数据需要以FormData形式提交。

下面是我推荐的写法

this.$axios.post(this.$rootPath+"/category/category",this.$qs.stringify(this.category))
public Object inserCategory(@ModelAttribute Category category) {}

注意:qs 默认会把 content-type 修改为 application/x-www-form-urlencoed。

好的,使用 axios表单数据提交给 Spring Boot 后端的实现步骤如下: 1. 在前端,获取表单数据可以使用 jQuery 的 serialize 方法,将表单中的数据序列化为 URL 编码的字符串。 2. 使用 axios 发送 POST 请求到 Spring Boot 后端,将序列化后的表单数据作为请求体发送。 3. 在 Spring Boot 后端,定义一个 POST 接口,使用 @RequestBody 注解将请求体中的数据映射为 Java 对象。 下面是一个基本的示例代码: ```javascript // HTML 表单 <form id="my-form"> <input type="text" name="username" value="" /> <input type="password" name="password" value="" /> <button type="submit">Submit</button> </form> // JavaScript 代码 $('#my-form').on('submit', function(event) { event.preventDefault(); // 阻止表单默认提交行为 var formData = $(this).serialize(); // 序列化表单数据 axios.post('url/to/springboot/api', formData) .then(function(response) { console.log(response.data); }) .catch(function(error) { console.log(error); }); }); // Spring Boot 后端代码 @RestController @RequestMapping("/api") public class MyController { @PostMapping("/submit") public String handleSubmit(@RequestBody MyForm form) { // 处理表单数据,form 对象中包含表单中的数据 return "success"; } } // 表单数据Java 对象定义 public class MyForm { private String username; private String password; // getter 和 setter 方法省略 } ``` 其中,`url/to/springboot/api` 是 Spring Boot 后端接口的 URL 地址,需要替换为实际的地址。`MyForm` 类是表单数据Java 对象定义,可以根据表单的实际情况进行修改。在后端,使用 @RequestBody 注解将请求体中的数据映射为 Java 对象,可以方便地进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值