文章目录
- 序列化
- 反序列化
- 在同一个class中序列化和反序列化
Spring Boot中使用@JsonComponent
@JsonComponent 是Spring boot的核心注解,使用@JsonComponent 之后就不需要手动将Jackson的序列化和反序列化手动加入ObjectMapper了。使用这个注解就够了。
序列化
假如我们有个User类,它里面有一个Color属性:
@Data@AllArgsConstructorpublic class User {private Color favoriteColor;}
接下来我们来创建针对User的序列化组件,我们需要实现JsonSerializer接口:
@JsonComponentpublic class UserJsonSerializer extends JsonSerializer<User> {@Overridepublic void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException,JsonProcessingException {jsonGenerator.writeStartObject();jsonGenerator.writeStringField("favoriteColor",getColorAsWebColor(user.getFavoriteColor()));jsonGenerator.writeEndObject();}private static String getColorAsWebColor(Color color) {int r = (int) Math.round(color.getRed() * 255.0);int g = (int) Math.round(color.getGreen() * 255.0);int b = (int) Math.round(color.getBlue() * 255.0);return String.format("#%02x%02x%02x", r, g, b);}}
在上面的类中,我们自定义了序列化的方法。接下来我们测试一下:
@JsonTest@RunWith(SpringRunner.class)public class UserJsonSerializerTest { @Autowiredprivate ObjectMapper objectMapper; @Testpublic void testSerialization() throws JsonProcessingException {User user = new User(Color.ALICEBLUE);String json = objectMapper.writeValueAsString(user); assertEquals("{\"favoriteColor\":\"#f0f8ff\"}", json);}}
反序列化
同样的,我们实现JsonDeserializer接口:
@JsonComponentpublic class UserJsonDeserializer extends JsonDeserializer<User> {@Overridepublic User deserialize(JsonParser jsonParser,DeserializationContext deserializationContext) throws IOException,JsonProcessingException {TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);TextNode favoriteColor= (TextNode) treeNode.get("favoriteColor");return new User(Color.web(favoriteColor.asText()));}}
我们看下怎么调用:
@JsonTest@RunWith(SpringRunner.class)public class UserJsonDeserializerTest { @Autowiredprivate ObjectMapper objectMapper; @Testpublic void testDeserialize() throws IOException {String json = "{\"favoriteColor\":\"#f0f8ff\"}"User user = objectMapper.readValue(json, User.class); assertEquals(Color.ALICEBLUE, user.getFavoriteColor());}}
在同一个class中序列化和反序列化
@JsonComponentpublic class UserCombinedSerializer { public static class UserJsonSerializer extends JsonSerializer<User> { @Overridepublic void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { jsonGenerator.writeStartObject();jsonGenerator.writeStringField( "favoriteColor", getColorAsWebColor(user.getFavoriteColor()));jsonGenerator.writeEndObject();} private static String getColorAsWebColor(Color color) {int r = (int) Math.round(color.getRed() * 255.0);int g = (int) Math.round(color.getGreen() * 255.0);int b = (int) Math.round(color.getBlue() * 255.0);return String.format("#%02x%02x%02x", r, g, b);}} public static class UserJsonDeserializer extends JsonDeserializer<User> { @Overridepublic User deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);TextNode favoriteColor = (TextNode) treeNode.get( "favoriteColor");return new User(Color.web(favoriteColor.asText()));}}}
为了方便,我们还可以在同一个类中定义两个内部类来实现序列化和反序列化。如上所示。
本文的例子可以参考https://github.com/ddean2009/learn-springboot2/tree/master/springboot-jsoncomponent