处理 json 和 HttpMessageConverter
2023年11月15日大约 8 分钟约 1638 字
处理 JSON-@ResponseBody
项目开发中,我们往往需要服务器返回的数据格式是按照 json 来返回的。
引入 jackson.jar

创建 Dog.java
package com.lzw.web.json.entity;
/**
* @author LiAng
*/
public class Dog {
private String name;
private String address;
public Dog() {
}
public Dog(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
创建 JsonHandler.java
package com.lzw.web.json;
import com.lzw.web.json.entity.Dog;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class JsonHandler {
/**
* 1. 目标方法 @ResponseBody,表示返回的数据是json格式
* 2. springmvc底层根据目标方法@ResponseBody, 返回指定格式, 根据http请求来进行处理
* 3. 这里原生的springmvc使用了转换器 HttpMessageConverter
*/
@RequestMapping(value = "/json/dog")
@ResponseBody
public Dog getJson(){
//返回对象
//springmvc会根据你的设置,转成json格式数据返回
Dog dog = new Dog();
dog.setName("大黄狗");
dog.setAddress("小新的家");
return dog;
}
}
创建 web\json.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>json提交</title>
<!-- 引入jquery -->
<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
<!-- 编写jquery代码和ajax请求 -->
<script type="text/javascript">
$(function(){
//给id="getJson"绑定点击事件
$("#getJson").click(function () {
var url = this.href;
var args = {"time":new Date()};//这是准备发送的数据,防止页面缓存
$.post(
url,
args,
function (data) {//data 就是返回的数据,是json格式=>如果是多个json数据,可以遍历
console.log("data= ", data);
console.log("dog.name= ", data.name);
console.log("dog.address= ", data.address);
},
"json"
);
return false;
})
})
</script>
</head>
<body>
<h1>请求一个json数据</h1>
<%--
1.当用户点击超链接时,我们发出一个ajax请求
2. 接收到请求后,我们查看这个数据
3. 使用jquery发出ajax请求知识
--%>
<a href="<%=request.getContextPath()%>/json/dog" id="getJson">点击获取json数据</a>
</body>
</html>
完成测试

处理 JSON-@RequestBody
- 客户端发送 json 字符串数据
- 使用 SpringMVC 的 @RequestBody 将客户端提交的 json 数据,封装成 JavaBean 对象
- 再把这个 javabean 以 json 对象形式返回
创建 User.java
package com.lzw.web.json.entity;
/**
* @author LiAng
*/
public class User {
private String userName;
private Integer age;
public User() {
}
public User(String userName, Integer age) {
this.userName = userName;
this.age = age;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", age=" + age +
'}';
}
}
修改 JsonHandler.java
/**
* 1. @RequestBody User user 在形参指定了 @RequestBody
* 2. springmvc就会将提交的json字符串数据填充给指定Javabean
*/
@RequestMapping(value = "/save2")
@ResponseBody
public User save2(@RequestBody User user){
//将前端传过来的数据,以json的格式响应回浏览器
System.out.println("user~= " + user);
return user;
}
修改 json.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>json提交</title>
<!-- 引入jquery -->
<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
<!-- 编写jquery代码和ajax请求 -->
<script type="text/javascript">
$(function(){
//给id="getJson"绑定点击事件
$("#getJson").click(function () {
var url = this.href;
var args = {"time":new Date()};//这是准备发送的数据,防止页面缓存
$.post(
url,
args,
function (data) {//data 就是返回的数据,是json格式=>如果是多个json数据,可以遍历
console.log("data= ", data);
console.log("dog.name= ", data.name);
console.log("dog.address= ", data.address);
},
"json"
);
return false;
});
//绑定按钮点击事件, 提交json数据
//springmvc 可以在后台將json转成對象
$("button[name='butt1']").click(function(){
//目标:将userName 和 age 封装成json字符串,发送给目标方法
var url = "/springmvc/save2";
var userName = $("#userName").val();
var age = $("#age").val();
//将json对象转成json字符串
var args = JSON.stringify({"userName": userName, "age": age})
$.ajax({
url:url,
data:args,
type:"POST",
success:function(data){
console.log("返回的data= ", data);
},
//下面这个contentType参数,是指定发送数据的编码和格式
contentType:"application/json;charset=utf-8"
})
})
})
</script>
</head>
<body>
<h1>请求一个json数据</h1>
<%--
1.当用户点击超链接时,我们发出一个ajax请求
2. 接收到请求后,我们查看这个数据
3. 使用jquery发出ajax请求知识
--%>
<a href="<%=request.getContextPath()%>/json/dog" id="getJson">点击获取json数据</a>
<h1>发出一个 json 数据</h1>
u:<input id="userName" type="text"><br/>
a:<input id="age" type="text"><br/>
<button name="butt1">添加用户</button>
</body>
</html>
完成测试


处理JSON-注意事项和细节
1.目标方法正常返回 JSON 需要的数据,可以是一个对象,也可以是一个集合。
修改 JsonHandler.java
//编写方法,以json格式返回多个Dog
@RequestMapping(value = "/json/dogs")
@ResponseBody
public List<Dog> getJsons() {
List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog("大黄狗", "小新的家"));
dogs.add(new Dog("大黄狗2", "小新2的家"));
dogs.add(new Dog("大黄狗3", "小新3的家"));
return dogs;
}

2.@ResponseBody 可以直接写在 controller 上,这样对所有方法生效

3.@ResponseBody + @Controller 可以直接写成 @RestController

HttpMessageConverter<T>
说明
SpringMVC 处理 JSON-底层实现是依靠 HttpMessageConverter<T>
来进行转换的。
工作机制

处理 JSON-底层实现(HttpMessageConverter<T>
)
使用 HttpMessageConverter<T>
将请求信息转化并绑定到处理方法的入参中,或将响应结果转为对应类型的响应信息,Spring 提供了两种途径:
(1)使用 @RequestBody / @ResponseBody 对目标方法进行标注
(2)使用 HttpEntity<T> / ResponseEntity<T>
作为目标方法的入参或返回值
- 当控制器处理方法使用到 @RequestBody/@ResponseBody 或
HttpEntity<T>/ResponseEntity<T>
时,Spring 首先根据请求头或响应头的 Accept 属性选择匹配的 HttpMessageConverter,进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter,若找不到可用的HttpMessageConverter 将报错。
文件下载
在 SpringMVC 中,通过返回 ResponseEntity<T>
的类型,可以实现文件下载的功能。
修改 JsonHandler.java
//响应用户下载文件的请求
@RequestMapping(value = "/downFile")
public ResponseEntity<byte[]> downFile(HttpSession session) throws Exception{
//1. 先获取到下载文件的inputStream
InputStream resourceAsStream = session.getServletContext().getResourceAsStream("/img/2.jpg");
//2. 开辟一个存放文件的byte数组, 这里使用byte[] 是可以支持二进制数据(图片,视频。)
byte[] bytes = new byte[resourceAsStream.available()];
//3. 将下载文件的数据,读入到byte[]
resourceAsStream.read(bytes);
//public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status) {}
//4. 创建返回的HttpStatus
HttpStatus httpStatus = HttpStatus.OK;
//5. 创建 headers
HttpHeaders headers = new HttpHeaders();
//指定返回的数据,客户端应当以附件形式处理
headers.add("Content-Disposition", "attachment;filename=2.jpg");
//构建一个ResponseEntity 对象1. 的http响应头headers 2. http响应状态 3. 下载的文件数据
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, httpStatus);
return responseEntity;
}
修改 json.jsp
<h1>下载文件的测试 </h1>
<a href="<%=request.getContextPath()%>/downFile">点击下载文件</a>
记得在项目中放上下载的资源

完成测试
