• 09【SpringMVC的Json支持】



    三、Json的支持

    SpringMVC支持自动将JSON转换成Java对象,也支持将Java对象自动转成JSON,SpringMVC本身没有对JSON数据处理的类库,要支持JSON的自动转换必须导入JSON的支持包

    Jackson依赖:

    <dependencies>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.2.9.RELEASEversion>
        dependency>
    
        
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-databindartifactId>
            <version>2.9.8version>
        dependency>
    
        <dependency>
            <groupId>org.apache.tomcatgroupId>
            <artifactId>tomcat-apiartifactId>
            <version>8.5.41version>
        dependency>
    
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.18version>
        dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3.1 响应json

    • 准备实体类:
    package com.dfbz.entity;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class City {
    
        private Integer id;         // 城市id
        private String cityName;    // 城市名称
        private Double GDP;         // 城市GDP,单位亿元
        private Boolean capital;    // 是否省会城市
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3.1.1 @ResponseBody

    作用:将响应的信息放入响应体中,默认情况下Java对象会被application/json处理;

    package com.dfbz.controller;
    
    import com.dfbz.entity.City;
    import com.dfbz.entity.Province;
    import com.dfbz.entity.Student;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    @Controller
    @RequestMapping("/demo01")
    public class Demo01Controller {
    
        @ResponseBody           // 将结果集以json形式响应
        @GetMapping("/demo01")
        public City demo01() throws Exception {
    
            City city = new City(1, "南昌", 5500.0, true);
            return city;
        }
    
        @ResponseBody           // 将结果集以json形式响应
        @GetMapping(value = "/demo02")
        public List<City> demo02() throws Exception {
    
            List<City> cityList = new ArrayList<>();
            cityList.add(new City(1, "南京", 14000.00, true));
            cityList.add(new City(2, "南通", 2400.00, false));
            cityList.add(new City(3, "南阳", 4000.00, false));
            return cityList;
        }
    
        @ResponseBody
        @GetMapping(value = "/demo03")
        public String demo03() throws Exception {
            return "hello";                 // 响应的信息被放在响应体中,而不是当做视图跳转
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    查看响应类型:

    在这里插入图片描述

    3.1.2 @JsonIgnore

    作用:将实体转换为json时指定忽略的属性;

    • Province:
    package com.dfbz.entity;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Province {
        private Integer id;
        private String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • City:
    package com.dfbz.entity;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class City {
    
        private Integer id;         // 城市id
        private String cityName;    // 城市名称
        private Double GDP;         // 城市GDP,单位亿元
        private Boolean capital;    // 是否省会城市
    
        @JsonIgnore
        private Province province;  // 所属省份
        
        public City(Integer id, String cityName, Double GDP, Boolean capital) {
            this.id = id;
            this.cityName = cityName;
            this.GDP = GDP;
            this.capital = capital;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • Controller:
    @ResponseBody           // 将结果集以json形式响应
    @RequestMapping(value = "/demo04")
    public City demo04() throws Exception{
    
        City city = new City(1, "南昌", 5500.0, true,new Province(1,"江西"));
        return city;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    访问:http://localhost:8080/demo/demo04(没有忽略province属性之前)

    在这里插入图片描述

    添加忽略属性后访问:http://localhost:8080/demo/demo04

    在这里插入图片描述

    3.1.3 @JsonFormat

    • 作用:将Date按照指定的格式转换为字符串
    package com.dfbz.entity;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.Date;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Student {
        private Integer id;
        private String name;
        private Integer age;
    
        private Date birthday;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • Controller:
    @ResponseBody
    @RequestMapping(value = "/demo05")
    public Student demo05() throws Exception{
        return new Student(1,"zhangsan",20,new Date());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    访问:http://localhost:8080/demo01/demo05

    在这里插入图片描述

    添加日期格式化注解:

    // 转换为json时按照什么格式进行转换
    @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    private Date birthday;
    
    • 1
    • 2
    • 3

    再次访问:http://localhost:8080/demo01/demo05

    在这里插入图片描述

    3.1.4 ResponseEntity

    作用:封装响应的信息

    /**
     * 响应ResponseEntity
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/demo06")
    public ResponseEntity<City> demo06() {
    
        // 响应体
        City city = new City(1, "南宁", 5000.0D, true, new Province(1, "广西"));
    
        // 响应头
        HttpHeaders headers = new HttpHeaders();
        headers.put("test", Arrays.asList("abc"));
    
        // 创建一个响应报文
        ResponseEntity<City> responseEntity = new ResponseEntity<>(city, headers, HttpStatus.OK);
    
        return responseEntity;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    访问:http://localhost:8080/demo01/demo06

    在这里插入图片描述

    3.1.5 作用在类上

    @ResponseBody注解不仅可以标注在方法上,还可以标注在类上,当该注解标注在类上时,该类的所有方法的返回值都会当作Json响应到前端;相当于在该类的所有的方法上都标注了@ResponseBody注解

    在这里插入图片描述

    package com.dfbz.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    @Controller
    @ResponseBody
    @RequestMapping("/test")
    public class TestController {
    
        @GetMapping("/hello")
        public String str() {
            return "hello @ResponseBody..";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    访问:http://localhost:8080/test/hello

    在这里插入图片描述

    3.1.6 @RestController

    @RestController是@Controller+@ResponseBody注解的整合版,拥有两个注解的功能,既能当前Bean注入到IOC容器,又能让当前Controller的所有方法的返回值以Json响应;

    package com.dfbz.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    //@Controller
    //@ResponseBody
    
    @RestController                 // @Controller+/@ResponseBody
    @RequestMapping("/test")
    public class TestController {
    
        @GetMapping("/hello")
        public String str() {
            return "hello @ResponseBody...";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3.2 请求Json

    3.2.1 @RequestBody

    作用:获取请求体的内容,注意:get请求方式是没有请求体的;

    package com.dfbz.controller;
    
    import com.dfbz.entity.Province;
    import com.dfbz.entity.Student;
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpHeaders;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    @Controller
    @RequestMapping("/demo02")
    public class Demo02Controller {
    
        /**
         * 获取请求体的参数
         *
         * @param str
         * @param response
         * @throws Exception
         */
        @RequestMapping("/demo01")
        public void demo01(@RequestBody String str, HttpServletResponse response) throws Exception {          // 获取请求体的内容
    
            System.out.println(str);
            response.getWriter().write(str);
            System.out.println("--------------");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • HTML表单:
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
        <script src="/js/jquery-3.5.1.min.js">script>
    head>
    <body>
    <form action="/demo02/demo01" method="post">
    
        <input type="text" name="id">
        <input type="text" name="name">
    
        <input type="submit">
    form>
    
    <button id="btn">sendRequestbutton>
    
    <script>
    
        $(function () {
            $("#btn").click(function () {
                var province = {id: 1, name: "吉林省"}
                $.post({
                    url: "/demo02/demo01",
                    
                    // 如果不加这一句,ajax默认的提交格式为: application/x-www-form-urlencoded
                    contentType: "application/json",
                    data: JSON.stringify(province),
                    success: function (res) {
                        console.log(res);
                    }
                })
            })
        })
    script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    分别使用表单提交和Json提交测试:

    在这里插入图片描述

    3.2.2 HttpEntity

    作用:接收前端提交的参数,包括请求体和请求头信息

    /**
     * 使用HttpEntity当做参数
     *
     * @param entity
     * @throws Exception
     */
    @RequestMapping("/demo02")
    @ResponseBody
    public String demo02(HttpEntity<String> entity) throws Exception {
        HttpHeaders headers = entity.getHeaders();        // 获取请求头
        System.out.println(headers);
        String provinceJsonStr = entity.getBody();                    // 获取请求体
        System.out.println(provinceJsonStr);
        System.out.println("----------------");
        return provinceJsonStr;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    访问:http://localhost:8080/demo02/demo02

    在这里插入图片描述

    3.2.3 封装Json数据

    @RequestBody不仅可以接收请求体中的参数,还可以将请求体数据为Json的转换为Java实体类型;

    /**
     * 把JSON数据转换为Java对象
     * @param province
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/demo03")
    public Province demo03(@RequestBody Province province) throws Exception {
        return province;
    }
    
    
    /**
     * 使用HttpEntity当做参数(封装成对象)
     *
     * @param entity
     * @throws Exception
     */
    @RequestMapping("/demo04")
    @ResponseBody
    public Province demo04(HttpEntity<Province> entity) throws Exception {
        HttpHeaders headers = entity.getHeaders();        // 获取请求头
        System.out.println(headers);
        Province province = entity.getBody();                    // 获取请求体
    
        return province;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 前端:
    $("#btn").click(function () {
    
        var json = {id: 1, name: "福建省"};
    
        // 必须将json对象转换为json字符串
        var jsonStr=JSON.stringify(json);
        $.post({		
           // url:"/demo02/demo03",				// 测试demo03和demo04
            url:"/demo02/demo04",
            data:jsonStr,		
            
            // 如果不加这一句,ajax默认的提交格式为: application/x-www-form-urlencoded
            contentType:"application/json",
            success:function (res) {
              	 console.log(res);
            }
        })
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    注意:JQuery在传递Json对象(不是Json字符串)数据到后台时,在底层会将Json对象转换为form表单进行传递;如果本次的提交类型(Content-Type)为application/x-www-form-urlencoded,那么在后端也是可以封装为Java对象的,前提是不能使用@RequestBody注解

    因此在使用JQuery的ajax提交时,传递Json对象到后端时不能使用@RequestBody注解接收参数,而是使用默认的表单数据封装方式,即什么注解都不写;

    /**
     * 接收表单提交的数据(JSON对象也可以)
     * @param province
     * @return
     * @throws Exception
     */
    @RequestMapping("/demo05")
    @ResponseBody
    public Province demo05(Province province) throws Exception {
        return province;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    表单和JSON对象提交:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
        <script src="/js/jquery-3.5.1.min.js">script>
    head>
    <body>
    <form action="/demo02/demo05" method="post">
    
        <input type="text" name="id">
        <input type="text" name="name">
    
        <input type="submit">
    form>
    
    <button id="btn">sendRequestbutton>
    
    <script>
    
        $(function () {
            $("#btn").click(function () {
                var province = {id: 1, name: "辽宁省"}
                $.post({
                    url: "/demo02/demo05",
                    
                    // 使用表单的请求方式(这也是默认的请求类型)			
                    contentType: "application/x-www-form-urlencoded",			
                    data: province,				// 直接提交JSON对象
                    success: function (res) {
                        console.log(res);
                    }
                })
            })
        })
    script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    点击sendRequest按钮发送请求,打开F12抓包工具:

    在这里插入图片描述

  • 相关阅读:
    第一类和第二类增值电信业务经营许可证的区别
    魔兽服务器学习-笔记1
    ​构建“顶流”合作圈,这家车联网企业已提前入局“半决赛”
    进程间通信的方式
    学会Hadoop源码,吊打字节跳动面试官!
    某验四代滑块验证码逆向分析
    GLOG 日志宏分析与PR合并
    maven中央仓库不能访问的解决办法
    ASEMI整流桥KBPC2510,KBPC2510参数,KBPC2510规格书
    java毕业设计在线售药系统Mybatis+系统+数据库+调试部署
  • 原文地址:https://blog.csdn.net/Bb15070047748/article/details/128105592