摘要:本文介绍了Springboot的JSON解析方案,包括自动化配置的Jackson和Gson,以及阿里的fastjson
SpringBoot的默认JSON解析方案
SpringBoot默认使用的是Jackson,在项目的maven依赖里面可以看到。同时SpringBoot也为我们自动配置好了Jackson和Gson的HttpMessageConverter。因此,如果用户使用Jackson和Gson时没有额外的自定义配置,则只需要引入依赖即可。
HttpMessageConverter是一个消息转换工具,其主要功能有:
- 将服务端返回的对象序列化成JSON字符串
- 将前端传来的JSON字符串反序列化为Java对象
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
那么我们使用一个简单的User类和UserController来测试一下SpringBoot的默认JSON解析方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package com.example.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; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package com.example.json.controller;
import com.example.json.bean.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; 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> getUsers() { List<User> userList = new ArrayList<>(); for (int i = 0; i < 10; i++) { User user = new User(); user.setId(i); user.setUsername("user:" + i); user.setAddress("home:" + i); user.setBirthday(new Date()); userList.add(user); } return userList; } }
|
运行后我们可以看到,使用默认的解析方案已经可以自动序列化JSON了
那么这些自动化配置是在哪里实现的呢?我们可以找到一个JacksonHttpMessageConvertersConfiguration类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Configuration(proxyBeanMethods = false) class JacksonHttpMessageConvertersConfiguration {
@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); } } ······ }
|
这里我们看到,该配置首先需要一个ObjectMapper,这是一个JSON序列化工具。然后再为其自动配置一个MappingJackson2HttpMessageConverter转换工具类。
那么如果我们想自己配置JSON的格式呢?比如说日期的格式,我们可以通过在User类中的birthday属性上添加@JsonFormat注解来局部格式化JSON,又或者我们可以通过创建一个配置类来自定义一个全局的JSON解析方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.example.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 messageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setDateFormat(new SimpleDateFormat("yyy-MM-dd")); converter.setObjectMapper(objectMapper); return converter; }
@Bean ObjectMapper objectMapper(){ ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setDateFormat(new SimpleDateFormat("yyy-MM-dd")); return objectMapper; } }
|
再次运行我们可以发现日期的格式改变了
SpringBoot整合Gson
现在我们来使用Gson的解析方案,我们已经说过SpringBoot已经为我们自动配置好了Gson,因此我们只需要引入依赖即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> </exclusion> </exclusions> </dependency>
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency>
|
添加完了依赖即可像上面使用Jackson那样使用Gson了。那么Gson的自动化配置又在哪里呢?我们找到一个GsonHttpMessageConvertersConfiguration类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Configuration(proxyBeanMethods = false) @ConditionalOnClass(Gson.class) class GsonHttpMessageConvertersConfiguration {
@Configuration(proxyBeanMethods = false) @ConditionalOnBean(Gson.class) @Conditional(PreferGsonOrJacksonAndJsonbUnavailableCondition.class) static class GsonHttpMessageConverterConfiguration {
@Bean @ConditionalOnMissingBean GsonHttpMessageConverter gsonHttpMessageConverter(Gson gson) { GsonHttpMessageConverter converter = new GsonHttpMessageConverter(); converter.setGson(gson); return converter; } } }
|
在这里我们可以看到若用户没有自定义一个GsonHttpMessageConverter的话,SpringBoot会自动为我们提供一个转换器。那么我们同样可以创建一个配置类来自定义Gson配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.example.gson.config;
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.GsonHttpMessageConverter;
@Configuration public class WebMvcConfig {
@Bean GsonHttpMessageConverter httpMessageConverter(){ GsonHttpMessageConverter converter = new GsonHttpMessageConverter(); converter.setGson(new GsonBuilder().setDateFormat("yyyy-MM-dd").create()); return converter; }
@Bean Gson gson(){ return new GsonBuilder().setDateFormat("yyyy-MM-dd").create(); } }
|
SpringBoot整合fastjson
SpringBoot没有自动配置fastjson的HttpMessageConverter,因此需要用户自己额外配置。
1 2 3 4 5
| <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.49</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.example.gson.config;
import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.GsonHttpMessageConverter;
@Configuration public class WebMvcConfig { FastJsonHttpMessageConverter httpMessageConverter(){ FastJsonHttpMessageConverter converter=new FastJsonHttpMessageConverter(); FastJsonConfig config = new FastJsonConfig(); config.setDateFormat("yyyy-MM-dd"); converter.setFastJsonConfig(config); return converter; } }
|