Spring Boot提供了三个JSON映射库的集成:
Jackson是首选的和默认的库。
为Jackson提供了自动配置,Jackson是spring-boot-starter-json的一部分。当Jackson在类路径上时,将自动配置ObjectMapper bean。提供了几个配置属性来定制ObjectMapper的配置。
如果您使用Jackson来序列化和反序列化JSON数据,您可能希望编写自己的JsonSerializer和JsonDeserializer类。自定义序列化器通常通过模块在Jackson中注册,但是Spring Boot提供了另一种@JsonComponent注释,可以更容易地直接注册Spring bean。
你可以直接在JsonSerializer、JsonDeserializer或KeyDeserializer的实现上使用@JsonComponent注释。你也可以在包含序列化器/反序列化器作为内部类的类上使用它,如下例所示:
- @JsonComponent
- public class MyJsonComponent {
-
- public static class Serializer extends JsonSerializer
{ -
- @Override
- public void serialize(MyObject value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
- jgen.writeStartObject();
- jgen.writeStringField("name", value.getName());
- jgen.writeNumberField("age", value.getAge());
- jgen.writeEndObject();
- }
-
- }
-
- public static class Deserializer extends JsonDeserializer
{ -
- @Override
- public MyObject deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
- ObjectCodec codec = jsonParser.getCodec();
- JsonNode tree = codec.readTree(jsonParser);
- String name = tree.get("name").textValue();
- int age = tree.get("age").intValue();
- return new MyObject(name, age);
- }
-
- }
-
- }
我测试一下,MyObject类:
- package com.example.demo.demos;
-
- public class MyObject {
- String name;
- int age;
-
- public MyObject() {
- }
-
- public MyObject(String name, int age) {
- this.name = name;
- this.age = age;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
- }
测试代码:
- @Test
- public void testSerialize() throws Exception {
- MyObject myObject = new MyObject("John", 30);
- ObjectMapper objectMapper = new ObjectMapper();
- String json = objectMapper.writeValueAsString(myObject);
- System.out.println(json);
- }
结果输出为:
话说,我每次都测试,各位真不打算关注一下吗?
测试反序列化:
- @Test
- public void testDeserialize() throws Exception {
- String json = "{\"name\":\"John\",\"age\":30}";
- ObjectMapper objectMapper = new ObjectMapper();
- MyObject myObject = objectMapper.readValue(json, MyObject.class);
- assertEquals("John", myObject.getName());
- assertEquals(30, myObject.getAge());
结果输出:没有问题,这个assertEquals方法就是判断两个参数的值是否相等。
ApplicationContext中的所有@JsonComponent bean都会自动注册到Jackson。因为@JsonComponent是用@Component做元注释的,所以应用了通常的组件扫描规则。
Spring Boot还提供了JsonObjectSerializer和JsonObjectDeserializer基类,它们在序列化对象时为标准Jackson版本提供了有用的替代方案。
上面的例子可以重写为使用JsonObjectSerializer/JsonObjectDeserializer,如下所示:
- @JsonComponent
- public class MyJsonComponent {
-
- public static class Serializer extends JsonObjectSerializer
{ -
- @Override
- protected void serializeObject(MyObject value, JsonGenerator jgen, SerializerProvider provider)
- throws IOException {
- jgen.writeStringField("name", value.getName());
- jgen.writeNumberField("age", value.getAge());
- }
-
- }
-
- public static class Deserializer extends JsonObjectDeserializer
{ -
- @Override
- protected MyObject deserializeObject(JsonParser jsonParser, DeserializationContext context, ObjectCodec codec,
- JsonNode tree) throws IOException {
- String name = nullSafeValue(tree.get("name"), String.class);
- int age = nullSafeValue(tree.get("age"), Integer.class);
- return new MyObject(name, age);
- }
-
- }
-
- }
Jackson支持mixins,可以用来将额外的注解混合到目标类中已经声明的注解中。Spring Boot的Jackson自动配置将扫描应用程序包中带有@JsonMixin注释的类,并将它们注册到自动配置的ObjectMapper中。注册由Spring Boot的JsonMixinModule执行。
为Gson提供了自动配置。当Gson在类路径上时,会自动配置一个Gson bean。几个spring.gson。* configuration属性用于自定义配置。为了获得更多的控制,可以使用一个或多个GsonBuilderCustomizer bean。
提供了JSON-B的自动配置。当JSON-B API和实现在类路径上时,将自动配置一个json bean。首选的JSON-B实现是为其提供依赖管理的Apache Johnzon