09【SpringMVC的Json支持】


三、Json的支持

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

Jackson依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>

    <!--Jackson依赖-->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.8</version>
    </dependency>

    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-api</artifactId>
        <version>8.5.41</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.18</version>
    </dependency>
</dependencies>

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;    // 是否省会城市
}

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";                 // 响应的信息被放在响应体中,而不是当做视图跳转
    }
}

查看响应类型:

在这里插入图片描述

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;
}
  • 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;
    }

}
  • Controller:
@ResponseBody           // 将结果集以json形式响应
@RequestMapping(value = "/demo04")
public City demo04() throws Exception{

    City city = new City(1, "南昌", 5500.0, true,new Province(1,"江西"));
    return city;
}

访问: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;
}
  • Controller:
@ResponseBody
@RequestMapping(value = "/demo05")
public Student demo05() throws Exception{
    return new Student(1,"zhangsan",20,new Date());
}

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

在这里插入图片描述

添加日期格式化注解:

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

再次访问: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;
}

访问: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..";
    }
}

访问: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...";
    }
}

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("--------------");
    }
}
  • HTML表单:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <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">sendRequest</button>

<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>

分别使用表单提交和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;
}

访问: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;
}
  • 前端:
$("#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);
        }
    })
})

注意: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;
}

表单和JSON对象提交:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <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">sendRequest</button>

<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>

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

緑水長流*z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值