前言
在实际开发中,我们在前后端传送数据通常使用Json格式,而在Spring MVC中返回Json格式的方式有多种,接下来我将介绍其中一些。
准备工作
为了演示Json格式的数据,我们准备一个实体类,例如User,这些可以测试java中最常见的类型list集合如何转换成Json格式数据。
User
public class User implements Serializable {
private int user_id;
private String user_name;
private String password;
public User(){}
public User(int user_id, String user_name, String password) {
this.user_id = user_id;
this.user_name = user_name;
this.password = password;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
注意:SpringMVC设置返回值为Json的方式多种多样,我列举出来的,只是我了解的返回方式
方式1:设置返回值为ModelAndView
@RequestMapping("/showJson1")
public ModelAndView showJsonInfo(){
ModelAndView mv =new ModelAndView();
List list=new ArrayList();
User user1 =new User(1,"小王","111");
User user2 =new User(2,"小明","222");
User user3 =new User(3,"小美","333");
list.add(user1);
list.add(user2);
list.add(user3);
mv.addObject("list",list);
mv.setView(new MappingJackson2JsonView());
return mv;
}
当我们使用ModelAndView作为返回值时,可以使用setView方法,将
new MappingJackson2JsonView() 作为实参传入,此时直接返回ModelAndView即可返回Json格式数据。
效果演示
方式2:使用@ResponseBody注解
@RequestMapping("/showJson2")
@ResponseBody
public User showJsonInfo2(){
User user3 =new User(3,"小美","333");
return user3;
}
此时返回值可以是对象类型,例如User;也可以是集合类型,例如List<User>,只要加上注解,返回值都会转换成Json
效果演示
方式3:使用@RestController注解
在类上添加@RestController注解,可以将该类下所有的控制器方法的返回值都转换成Json格式
@RestController
public class TestController2 {
@RequestMapping("test2")
public User getUserJson(){
User user =new User(1,"第一名","123");
return user;
}
}
查看源码可知,@RestController注解中包含了@ResponseBody,如下:
效果演示
注意事项
- @ResponseBody既可以作为方法注解,也可以作为类注解
- 从Spring 4.0开始,@ResponseBody注解也可以被添加到类级别上。
- 因此,在这里@RestController等价于@Controller+@ResponseBody
方法4:使用ResponseEntity
ResponseEntity
提供了一种更灵活的方式来构建HTTP响应,包括状态码、头部信息和响应体。你可以将JSON对象作为响应体返回。
@Controller
public class TestController3 {
@RequestMapping("/testEntity")
public ResponseEntity<User>getJson(){
User user =new User(2,"第二名也不错","111");
return ResponseEntity.ok(user);
}
}
将方法的返回值设置为 ResponseEntity<要转换成Json的类型>,这个类型可以是对象也可以是集合。return 返回ResponseEntity.ok(数据); 调用ResponseEntity中的静态方法ok,将数据转换成Json格式并返回
效果演示
@Controller
public class TestController3 {
@RequestMapping("/testEntity")
public ResponseEntity<List<User> >getJson(){
User user =new User(2,"第二名也不错","111");
List<User> list=new ArrayList<>();
list.add(user);
return ResponseEntity.ok(list);
}
}
效果演示
方法5:手动序列化为JSON字符串
注意事项:如果使用的是jetty服务器插件,需要保证服务器版本为
才能正常启动成功
第一步:导入ObjectMapper依赖
<!--需要导入com.fasterxml.jackson.databind.ObjectMapper-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version> <!-- 确保使用最新的稳定版本 -->
</dependency>
第二步:测试
@Controller
public class TestController4 {
private ObjectMapper objectMapper=new ObjectMapper();
@RequestMapping("/JsonSerializable")
public String getSerializable() throws JsonProcessingException {
User user =new User(3,"第三名","333");
String str=objectMapper.writeValueAsString(user);
System.out.println(str);
return str;
}
}
效果演示
可以看到,手动序列化的方式,将我们的数据直接转换成了Json格式的字符串数据,返回前端时,被视图解析器解析,认为字符串时一个视图名,所以显示出错。
解决方案:
加上@ResponseBody注解,
此时出现中文乱码,
问题分析:按f12,发现浏览器的响应字符编码为iso-8859-1,我们后台设置为utf-8
解决思路:设置编码集一致
总结
对于大多数用例来说,使用
@RestController
或@ResponseBody
注解是最简单和最直接的方法。如果你需要更细粒度的控制,可以考虑使用ResponseEntity
或手动序列化。在全局范围内修改响应体时,可以使用ResponseBodyAdvice
接口。无论选择哪种方法,都应该确保你的项目中包含了适当的JSON处理库(如Jackson)。