经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
实例详解SpringBoot默认的JSON解析方案
来源:jb51  时间:2021/8/16 18:51:40  对本文有异议

一、什么是JSON

JSON(JavaScript Object Notation)是一种基于JavaScript语法子集的开放标准数据交换格式。JSON是基于文本的,轻量级的,通常被认为易于读/写。

好了,废话不多说,下面开始介绍如何在SpringBoot中使用JSON。

二、如何在SpringBoot中使用JSON

在学习json之前,我们必须先了解一下HttpMessageConverter,其实看名字就知道,这是一个消息转换工具。

下面我来介绍一下它的两个功能:

1、将服务端返回的对象序列化成 JSON 字符串。

2、将前端传来的 JSON 字符串反序列化成 Java 对象。

所有的 JSON 生成都离不开相关的 HttpMessageConverter。

SpringMVC 自动配置了 Jackson 和 Gson 的 HttpMessageConverter,Spring Boot 中又对此做了自动化配置,下面是两者对应源码的路径:

  1. org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration
  1. org.springframework.boot.autoconfigure.http.GsonHttpMessageConvertersConfiguration

所以,如果用户使用 jackson 和 gson 的话,没有其他额外配置,则只需要添加依赖即可。

三、举例

第一步】老规矩,先创建一个SpringBoot项目。通过右边的Maven可以看到,其实SpringBoot已经将json集成进来了,Maven结构如下图:

第二步】创建一个bean和一个controller类,具体项目结构和代码如下:

【项目结构】

【User.java】

  1. package com.mango.json.bean;
  2.  
  3. import com.fasterxml.jackson.annotation.JsonFormat;
  4.  
  5. import java.util.Date;
  6.  
  7. public class User {
  8.  
  9. private Integer id;
  10. private String username;
  11. private String address;
  12. public Integer getId() {
  13. return id;
  14. }
  15.  
  16. public void setId(Integer id) {
  17. this.id = id;
  18. }
  19.  
  20. public String getUsername() {
  21. return username;
  22. }
  23.  
  24. public void setUsername(String username) {
  25. this.username = username;
  26. }
  27.  
  28. public String getAddress() {
  29. return address;
  30. }
  31.  
  32. public void setAddress(String address) {
  33. this.address = address;
  34. }
  35. }

【UserController.java】

  1. package com.mango.json.controller;
  2.  
  3. import com.mango.json.bean.User;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.ResponseBody;
  7. import org.springframework.web.bind.annotation.RestController;
  8.  
  9. import java.util.ArrayList;
  10. import java.util.Date;
  11. import java.util.List;
  12.  
  13. @RestController
  14. public class UserController {
  15.  
  16. @GetMapping("/user")
  17. public List<User> getUser() {
  18. List<User> userList = new ArrayList<>();
  19. for (int i = 0; i < 10; i++) {
  20. User user = new User();
  21. user.setId(i);
  22. user.setUsername("mango>>>" + i);
  23. user.setAddress("www.mango.com>>>" + i);
  24. user.setBirthday(new Date());
  25. userList.add(user);
  26. }
  27. return userList;
  28. }
  29. }

【运行结果】

注:大家可能和我显示的效果不一样,但是内容肯定是一样的,如果需要显示成我这样格式,需要给浏览器装一款插件JSONView,这款插件就专门为json格式设计的,因为很复杂的json格式,是不容易阅读的。

四、拓展

上面就是SpringBoot中json的简单用法,下面我会再针对json进行一点内容的拓展。

1、如果碰到bean中有日期类型的属性,json该怎么处理日期格式?

第一种办法】我们可以在该属性上添加@JsonFormat(pattern = “yyyy-MM-dd”)注解,代码如下:

  1. package com.mango.json.bean;
  2.  
  3. import com.fasterxml.jackson.annotation.JsonFormat;
  4.  
  5. import java.util.Date;
  6.  
  7. public class User {
  8.  
  9. private Integer id;
  10. private String username;
  11. private String address;
  12. @JsonFormat(pattern = "yyyy-MM-dd")
  13. private Date birthday;
  14.  
  15. public Date getBirthday() {
  16. return birthday;
  17. }
  18.  
  19. public void setBirthday(Date birthday) {
  20. this.birthday = birthday;
  21. }
  22.  
  23. public Integer getId() {
  24. return id;
  25. }
  26.  
  27. public void setId(Integer id) {
  28. this.id = id;
  29. }
  30.  
  31. public String getUsername() {
  32. return username;
  33. }
  34.  
  35. public void setUsername(String username) {
  36. this.username = username;
  37. }
  38.  
  39. public String getAddress() {
  40. return address;
  41. }
  42.  
  43. public void setAddress(String address) {
  44. this.address = address;
  45. }
  46. }

如果该bean中存在许多日期类型的属性呢,这么做就不是那么合适了,所以,可以采用下面的第二种办法。

第二种办法】大家都知道json肯定离不开ObjectMapper,因为json格式和java中的对象之间进行转换就是通过ObjectMapper类,想深入研究的朋友可以看看这个类的源码。

在上面我提到了SpringBoot自动化配置json,也给出了json源码的路径,大家可以进去看看,是否看到下面一段代码,这就是它的核心之处。

  1. @Configuration(proxyBeanMethods = false)
  2. @ConditionalOnClass(ObjectMapper.class)
  3. @ConditionalOnBean(ObjectMapper.class)
  4. @ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY,
  5. havingValue = "jackson", matchIfMissing = true)
  6. static class MappingJackson2HttpMessageConverterConfiguration {
  7.  
  8. @Bean
  9. @ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class,
  10. ignoredType = {
  11. "org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter",
  12. "org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" })
  13. MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
  14. return new MappingJackson2HttpMessageConverter(objectMapper);
  15. }
  16.  
  17. }

其中,mappingJackson2HttpMessageConverter方法就是我们需要用到的,这是SpringBoot为我们默认提供的,如果我们不重写这个方法,默认它就会生效,反之则失效。换句话说,我们不管是否重写该方法,json我们都可以用。

既然我们现在有需求了,我们就重写这个方法,具体代码如下:

【WebMvcConfig.java】

  1. package com.mango.json.config;
  2.  
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
  7.  
  8. import java.text.SimpleDateFormat;
  9.  
  10. @Configuration
  11. public class WebMvcConfig {
  12.  
  13. @Bean
  14. MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
  15. MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
  16. ObjectMapper objectMapper = new ObjectMapper();
  17. objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
  18. converter.setObjectMapper(objectMapper);
  19. return converter;
  20. }
  21. }

注:重写这个方法后,我们可以将bean中的注解@JsonFormat(pattern = “yyyy-MM-dd”)注释掉,重启项目即可。(如果大家有兴趣,可以进行debug调试,看看默认的方法是否还有效)

其实,大家可以从上面的代码看到,我们真正对日期格式进行设置的是对ObjectMapper进行操作的,所以这段重写的代码是否可以精简呢?答案是:当然可以。

有心的朋友肯定留意到了,上面SpringBoot默认提供的mappingJackson2HttpMessageConverter(ObjectMapper objectMapper)方法中,是存在ObjectMapper的,至于这个ObjectMapper是从哪里来的,大家可以根据下面路径中的源码看看:

【JacksonAutoConfiguration.java源码路径】

  1. org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration

【具体源码如下】

  1. @Configuration(proxyBeanMethods = false)
  2. @ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
  3. static class JacksonObjectMapperConfiguration {
  4.  
  5. @Bean
  6. @Primary
  7. @ConditionalOnMissingBean
  8. ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
  9. return builder.createXmlMapper(false).build();
  10. }
  11.  
  12. }

对,其实mappingJackson2HttpMessageConverter(ObjectMapper objectMapper)方法中ObjectMapper就是上面源码中jacksonObjectMapper方法返回的ObjectMapper,大家可以debug试一下,看看是否正确。

废话不多说了,下面我就重写ObjectMapper,具体代码如下:

【WebMvcConfig.java】

  1. package com.mango.json.config;
  2.  
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
  7.  
  8. import java.text.SimpleDateFormat;
  9.  
  10. @Configuration
  11. public class WebMvcConfig {
  12.  
  13. /*@Bean
  14. MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
  15. MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
  16. ObjectMapper objectMapper = new ObjectMapper();
  17. objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
  18. converter.setObjectMapper(objectMapper);
  19. return converter;
  20. }*/
  21.  
  22. @Bean
  23. ObjectMapper objectMapper(){
  24. ObjectMapper objectMapper = new ObjectMapper();
  25. objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
  26. return objectMapper;
  27. }
  28. }

【运行结果】

注:因为上面两种方法最后的结果都是一样的,所以运行结果图只放一张。

总结

到此这篇关于SpringBoot默认的JSON解析方案的文章就介绍到这了,更多相关SpringBoot默认JSON解析内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号