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>
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; // 是否省会城市
}
作用:将响应的信息放入响应体中,默认情况下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"; // 响应的信息被放在响应体中,而不是当做视图跳转
}
}
查看响应类型:
作用:将实体转换为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 Province {
private Integer id;
private String name;
}
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;
}
}
@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
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;
}
@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
作用:封装响应的信息
/**
* 响应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
@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
@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...";
}
}
作用:获取请求体的内容,注意: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("--------------");
}
}
<%@ 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>
分别使用表单提交和Json提交测试:
作用:接收前端提交的参数,包括请求体和请求头信息
/**
* 使用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
@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>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>
点击sendRequest
按钮发送请求,打开F12抓包工具: