您觉得本文档还缺少什么内容?可以自己补充~

为了统一参数格式和数据精度丢失等问题,本项目做了采用jackson进行全局的序列化和反序列化配置。

名词解释:

  1. 序列化:Controller层接口返回值 转成 json 格式的过程
  2. 反序列化:前端请求通过json格式提交参数到 Controller 层的过程

全局配置

在BaseConfig类配置了全局的ObjectMapper 实例, 并对objectMapper进行了自定义配置。 注意:配置全局ObjectMapper类后,会和yml配置文件中 spring.jackson.xxx 的配置产生冲突,所以请勿在yml中重复配置

@Bean
@Primary
@ConditionalOnClass(ObjectMapper.class)
@ConditionalOnMissingBean
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
    ObjectMapper objectMapper = builder.createXmlMapper(false).build();

    objectMapper
     // 设置当前位置
    .setLocale(Locale.CHINA)
    //去掉默认的时间戳格式
    .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
    // 时区
    .setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()))
    //Date参数日期格式
    .setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT, Locale.CHINA))
    //该特性决定parser是否允许JSON字符串包含非引号控制字符(值小于32的ASCII字符,包含制表符和换行符)。 如果该属性关闭,则如果遇到这些字符,则会抛出异常。JSON标准说明书要求所有控制符必须使用引号,因此这是一个非标准的特性
    .configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true)
    // 忽略不能转义的字符
    .configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true)
    //在使用spring boot + jpa/hibernate,如果实体字段上加有FetchType.LAZY,并使用jackson序列化为json串时,会遇到SerializationFeature.FAIL_ON_EMPTY_BEANS异常
    .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
    //忽略未知字段
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    //单引号处理
    .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
    // 注册自定义模块
    objectMapper.registerModule(new BcJacksonModule())
    .registerModule(new SimpleModule().addDeserializer(RemoteData.class, RemoteDataDeserializer.INSTANCE))
    .findAndRegisterModules();
}

序列化自定义配置项

  1. Long -> String

    1) 实现代码

public BcJacksonModule() {
    this.addSerializer(Long.class, ToStringSerializer.instance);
    this.addSerializer(Long.TYPE, ToStringSerializer.instance);
}

​ 2)最终效果

Controller层接口返回参数中,Long类型的字段,会转成字符串。

{
    "id": "29984253320102284"
}

​ 3)解决问题: 解决前端获取到Long类型的字段后,精度丢失问题。 (更多信息自行百度&谷歌)

  1. BigInteger -> String 1) 实现代码
public BcJacksonModule() {
    this.addSerializer(BigInteger.class, ToStringSerializer.instance);
}

​ 2) 最终效果&解决问题:同上

  1. BigDecimal -> String 1) 实现代码
public BcJacksonModule() {
    this.addSerializer(BigDecimal.class, ToStringSerializer.instance);
}

​ 2) 最终效果&解决问题:同上

  1. Date -> String 1) 实现代码
public class BaseConfig {
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
objectMapper
//Date参数日期格式
.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT, Locale.CHINA))
// ...
}
}

​ 2) 最终效果 Controller层接口返回参数中,Date类型的字段,会转成字符串。

{
    "date": "yyyy-MM-dd HH:mm:ss"  // 这里的格式由上面的 DEFAULT_DATE_TIME_FORMAT 决定
}

​ 3)解决问题: 统一日期参数的统一格式

  1. LocalDateTime -> String 1) 实现代码
public BcJacksonModule() {
    this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
}

​ 2) 最终效果 Controller层接口返回参数中,LocalDateTime类型的字段,会转成字符串。

{
    "createTime": "yyyy-MM-dd HH:mm:ss"
}

​ 3)解决问题: 同上

  1. LocalDate -> String 1) 实现代码
public BcJacksonModule() {
    this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
}

​ 2) 最终效果 Controller层接口返回参数中,LocalDate类型的字段,会转成字符串。

{
    "createTime": "yyyy-MM-dd"
}

​ 3)解决问题: 同上

  1. LocalTime -> String 1) 实现代码
public BcJacksonModule() {
    this.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
}

​ 2) 最终效果 Controller层接口返回参数中,LocalTime类型的字段,会转成字符串。

{
    "createTime": "HH:mm:ss"
}

​ 3)解决问题: 同上

反序列化自定义配置项

  1. String -> Long
  2. Object -> BaseEnum
  3. String -> BaseEnum
  4. String -> LocalDate, 支持前端传递格式:

  5. yyyy-MM-dd: 如:2021-11-11

  6. String -> LocalDateTime, 支持前端传递格式:

  7. yyyy-MM-dd: 如:2021-11-11

  8. yyyy/MM/dd: 如:2021/11/11
  9. yyyy年MM月dd日: 如:2021年11月11日
  10. yyyy-MM-dd HH:mm:ss: 如:2021-11-11 11:11:11
  11. yyyy/MM/dd HH:mm:ss: 如:2021/11/11 11:11:11
  12. yyyy年MM月dd日HH时mm分ss秒: 如:2021年11月11日11时11分11秒

  13. String -> LocalTime 支持前端传递格式: HH:mm:ss

  14. Object -> RemoteData
  15. String -> RemoteData 1) 实现代码:以上几点的实现代码均在 BcJacksonModule 类 2) 最终效果:按照上述序列化的 参数格式提交json参数,会自动将参数封装到入参对象中 3) 解决问题:实现参数格式统一化(序列化和反序列化格式统一),并且为了减少报错率,BaseEnum和RemoteData类型的参数,在传递时,既可以以字符串的格式传递,也可以以object的格式传递。如:
{
    "sex": "M",// 格式1
    "sex": {
        "code": "M" // 格式2
    }.
    "createTime": "yyyy-MM-dd HH:mm:ss"
}

results matching ""

    No results matching ""