前端发送POST请求,后端数据收到为null解决方案、@RequestBody注解的详细使用、content-type决定了发送什么类型的数据

前端通过POST请求发送数据,并且通过F12也可查看到具体数据,但后端数据接收到为null的情况。

前端是这样发送的数据

this.$axios
          .post('/books', {
    
    
            id: this.form.id,
            cover: this.form.cover,
            title: this.form.title,
            author: this.form.author,
            date: this.form.date,
            press: this.form.press,
            abs: this.form.abs,
            cid: this.form.cid
          }).then(resp => {
    
    
          if (resp && resp.status === 200) {
    
    
            this.dialogFormVisible = false
          }
        })

打开开发者工具F12NetWork界面查看请求数据
在这里插入图片描述
请求发送成功并且数据也没问题,数据的发送类型:
在这里插入图片描述
以JSON形式发送,查看后端的数据接收情况:
在这里插入图片描述
查看我们后端mvc的controller配置

@PostMapping("/books")
    public void updateBook(Book book) throws Exception{
    
    
        System.out.println(book);
        bookService.updateBook(book);
    }

很明显,我是以Book实体类来接收JSON数据,JSON数据是放在post请求body(请求体)当中的,而我们以实体类来接收当然不会接收数据。
**解决方式:**加@RequestBody注解来将JSON数据封装给JAVABean类型

@PostMapping("/books")
    public void updateBook(@RequestBody Book book) throws Exception{
    
    
        System.out.println(book);
        bookService.updateBook(book);
    }

这样后端便可以接收到数据了
在这里插入图片描述

不使用@RequestBody注解,如果是以post请求将数据放在请求头的参数中情况会是怎么样呢?
打开PostMan工具,将数据放在请求头当中
在这里插入图片描述
后端接收到了数据:
在这里插入图片描述
这种情况总结
1、以POST请求将数据放在请求体当中,后端需要使用@RequestBody注解来对JAVABean类型数据进行封装。
2、将参数放在请求头中,会自动对数据封装,不使用@RequestBody注解也可以。
原因: 后端根据不同的Content-Type等情况,Spring-MVC会采取不同的HttpMessageConverter实现来进行信息转换解析,数据放在请求体中,Content-Type类型为application/json,数据放在请求头中,Content-Type类型为application/x-www-form-urlencoded

谷歌浏览器也会根据Content-Type的类型不同将数据在开发者工具中显示不同,如果是json类型就会显示Request Payload,如果是form,就会显示Form Data。

上述情况分析完了,接下来看下什么情况该使用@RequestBody注解,什么情况不该使用。

@ReqestBody注解

1、第一种情况就是上面这种,前端发送数据类型为json数据,后端使用@RequestBody注解来自动对数据封装。

对于这种情况有点需要注意一下,如果是String类型而不是JAVABean类型,使用了该注解,则接受到的json数据转换为String类型,并且数据内容是json形式的字符串,看:
通过PostMan发送json数据,首先设置请求头将Content-Type类型设置为application/json类型
在这里插入图片描述
发送请求体
在这里插入图片描述
看下后端的数据:json形式的字符串
在这里插入图片描述
我们要使用还得把这个数据给提取出来。
首先导入对应jar包

<!-- JSONObject对象依赖的jar包 -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>net.sf.ezmorph</groupId>
            <artifactId>ezmorph</artifactId>
            <version>1.0.6</version>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.2.3</version>
            <classifier>jdk15</classifier><!-- 指定jdk版本 -->
        </dependency>
        <!-- Json依赖架包下载 -->

进行数据提取

@RequestMapping("/testJson")
    public String testJson3(@RequestBody String string) {
    
    
    	// 将string类型转换为json数据
        JSONObject json = JSONObject.fromObject(string);
        // 使用JSONObject类的get方法提取属性
        Object string1 = json.get("string");
        // 再转换为string类型
        String s = string1.toString();
        System.out.println("object:string1:"+string1);
        return string;
    }

很明显,繁琐,所以这种一个数据我们还是使用get方式将参数放在url中合适。

2、前端发送数据类型为form-data类型,后端不使用@RequestBody注解。

使用ajax发送post请求时数据都默认为json类型,如果是表单设置post请求,发送到后端,默认为form-data类型,前面说的数据放在请求头中,就是该情况,后端会自动对数据进行封装,无论是JAVABean类型还是基本类型,当然如果数据较多还是放在请求体中比较好。
在这里插入图片描述
参考文章:
1、Form-data与Request-Payload
2、RequestBody的使用
3、JSON与String类型相互转换

猜你喜欢

转载自blog.csdn.net/qq_44660367/article/details/109200593