SpringBoot默认JSON解析 实例详解SpringBoot默认的JSON解析方案
我要大芒果 人气:0一、什么是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 中又对此做了自动化配置,下面是两者对应源码的路径:
org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration
org.springframework.boot.autoconfigure.http.GsonHttpMessageConvertersConfiguration
所以,如果用户使用 jackson 和 gson 的话,没有其他额外配置,则只需要添加依赖即可。
三、举例
【第一步】老规矩,先创建一个SpringBoot项目。通过右边的Maven可以看到,其实SpringBoot已经将json集成进来了,Maven结构如下图:
【第二步】创建一个bean和一个controller类,具体项目结构和代码如下:
【项目结构】
【User.java】
package com.mango.json.bean; import com.fasterxml.jackson.annotation.JsonFormat; import java.util.Date; public class User { private Integer id; private String username; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
【UserController.java】
package com.mango.json.controller; import com.mango.json.bean.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.Date; import java.util.List; @RestController public class UserController { @GetMapping("/user") public List<User> getUser() { List<User> userList = new ArrayList<>(); for (int i = 0; i < 10; i++) { User user = new User(); user.setId(i); user.setUsername("mango>>>" + i); user.setAddress("www.mango.com>>>" + i); user.setBirthday(new Date()); userList.add(user); } return userList; } }
【运行结果】
注:大家可能和我显示的效果不一样,但是内容肯定是一样的,如果需要显示成我这样格式,需要给浏览器装一款插件JSONView,这款插件就专门为json格式设计的,因为很复杂的json格式,是不容易阅读的。
四、拓展
上面就是SpringBoot中json的简单用法,下面我会再针对json进行一点内容的拓展。
1、如果碰到bean中有日期类型的属性,json该怎么处理日期格式?
【第一种办法】我们可以在该属性上添加@JsonFormat(pattern = “yyyy-MM-dd”)注解,代码如下:
package com.mango.json.bean; import com.fasterxml.jackson.annotation.JsonFormat; import java.util.Date; public class User { private Integer id; private String username; private String address; @JsonFormat(pattern = "yyyy-MM-dd") private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
如果该bean中存在许多日期类型的属性呢,这么做就不是那么合适了,所以,可以采用下面的第二种办法。
【第二种办法】大家都知道json肯定离不开ObjectMapper,因为json格式和java中的对象之间进行转换就是通过ObjectMapper类,想深入研究的朋友可以看看这个类的源码。
在上面我提到了SpringBoot自动化配置json,也给出了json源码的路径,大家可以进去看看,是否看到下面一段代码,这就是它的核心之处。
@Configuration(proxyBeanMethods = false) @ConditionalOnClass(ObjectMapper.class) @ConditionalOnBean(ObjectMapper.class) @ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, havingValue = "jackson", matchIfMissing = true) static class MappingJackson2HttpMessageConverterConfiguration { @Bean @ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class, ignoredType = { "org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter", "org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" }) MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) { return new MappingJackson2HttpMessageConverter(objectMapper); } }
其中,mappingJackson2HttpMessageConverter方法就是我们需要用到的,这是SpringBoot为我们默认提供的,如果我们不重写这个方法,默认它就会生效,反之则失效。换句话说,我们不管是否重写该方法,json我们都可以用。
既然我们现在有需求了,我们就重写这个方法,具体代码如下:
【WebMvcConfig.java】
package com.mango.json.config; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.text.SimpleDateFormat; @Configuration public class WebMvcConfig { @Bean MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){ MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); converter.setObjectMapper(objectMapper); return converter; } }
注:重写这个方法后,我们可以将bean中的注解@JsonFormat(pattern = “yyyy-MM-dd”)注释掉,重启项目即可。(如果大家有兴趣,可以进行debug调试,看看默认的方法是否还有效)
其实,大家可以从上面的代码看到,我们真正对日期格式进行设置的是对ObjectMapper进行操作的,所以这段重写的代码是否可以精简呢?答案是:当然可以。
有心的朋友肯定留意到了,上面SpringBoot默认提供的mappingJackson2HttpMessageConverter(ObjectMapper objectMapper)方法中,是存在ObjectMapper的,至于这个ObjectMapper是从哪里来的,大家可以根据下面路径中的源码看看:
【JacksonAutoConfiguration.java源码路径】
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
【具体源码如下】
@Configuration(proxyBeanMethods = false) @ConditionalOnClass(Jackson2ObjectMapperBuilder.class) static class JacksonObjectMapperConfiguration { @Bean @Primary @ConditionalOnMissingBean ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { return builder.createXmlMapper(false).build(); } }
对,其实mappingJackson2HttpMessageConverter(ObjectMapper objectMapper)方法中ObjectMapper就是上面源码中jacksonObjectMapper方法返回的ObjectMapper,大家可以debug试一下,看看是否正确。
废话不多说了,下面我就重写ObjectMapper,具体代码如下:
【WebMvcConfig.java】
package com.mango.json.config; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.text.SimpleDateFormat; @Configuration public class WebMvcConfig { /*@Bean MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){ MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); converter.setObjectMapper(objectMapper); return converter; }*/ @Bean ObjectMapper objectMapper(){ ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); return objectMapper; } }
【运行结果】
注:因为上面两种方法最后的结果都是一样的,所以运行结果图只放一张。
总结
加载全部内容