Jackson给给指定类设置序列化规则

发布时间 2023-12-21 14:33:52作者: 六月瓜

背景

业务中需要对返回给APP端的数据进行特殊处理,包括:

  • null值转换成空字符串
  • 日期(LocalDateTime)类型转换成时间戳
  • 金额根据用户Locale做格式化

需要保证不影响内部其他服务的互相调用,因此让所有返回给APP的VO对象实现自定义的Vo接口,然后指定对Vo接口的类进行对应的转换。

实现com.fasterxml.jackson.databind.JsonSerializer接口实现序列化方式

public class AppVoSerializer extends JsonSerializer<Vo> {
    private final ObjectMapper objectMapper = new ObjectMapper();

    public AppVoSerializer() {
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString(Strings.EMPTY);
            }
        });
        SimpleModule simpleModule = new SimpleModule("customerSerializationModule", new Version(1, 0, 0, "static version", "", ""));
        simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        simpleModule.addSerializer(BigDecimal.class, new BigDecimalSerializer());
        objectMapper.registerModule(simpleModule);
    }

    @Override
    public void serialize(Vo appVo, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeObject(new JSONObject(objectMapper.writeValueAsString(appVo)));
    }
}

实现org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer接口指定类

@Configuration
public class JacksonConfig implements Jackson2ObjectMapperBuilderCustomizer {
    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        jacksonObjectMapperBuilder.serializerByType(Vo.class, new AppVoSerializer());
    }
}

附上LocalDateTimeSerializer

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    @Override
    public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        long timestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        jsonGenerator.writeString(String.valueOf(timestamp / 1000));
    }
}

附上BigDecimalSerializer

public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {
    @Override
    public void serialize(BigDecimal bigDecimal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        Locale locale = ThreadContext.getUser().getUserLocale();
        NumberFormat numberFormat = DecimalFormat.getInstance(locale);
        String format = numberFormat.format(bigDecimal);
        jsonGenerator.writeString(format);
    }
}