反序列化问题

  • 反序列化不存在的properties时,报错,需要注解 @JsonIgnoreProperties
  • 反序列化未知的enum时,报错

如果不希望报错,那么需要修改Jackson 配置。

Jackson 配置

方法一:修改 objectMapper 的 configuration

public class JsonUtil {
    private static ObjectMapper mapper;

    static {
        mapper = new ObjectMapper();
        // ...

        // ignore unknown properties
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // unknown enum -> null
        mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
        // include none null
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }
}

方法二:修改application.yaml配置

spring:
  # Jackson 配置
  jackson:
    # Include NON_NULL
    default-property-inclusion: non_null
    # 反序列化
    deserialization:
      # ignore unknown property
      fail-on-unknown-properties: false
      # unknown enum -> null
      read-unknown-enum-values-as-null: true

Have a test!

example enum:

public enum RateSpan {

    W01("近一周"),
    M01("近一个月"), M03("近三个月"), M06("近六个月"),
    Y01("近一年"), Y03("近三年"), Y00("今年以来"), YGB("成立以来");

    final String msg;

    RateSpan(String msg) {
        this.msg = msg;
    }
    public String getMsg() {
        return msg;
    }
}
class RateSpanTest {
    @Test void deserialize() throws JsonProcessingException {
        // "Y01" -> Y01
        RateSpan span = JsonUtil.loadStr("\"Y01\"", RateSpan.class);
        assertEquals(span, RateSpan.Y01);
        // "FUCK" -> null
        span = JsonUtil.loadStr("\"FUCK\"", RateSpan.class);
        assertNull(span);
    }
}

More

除了反序列化为 null,我们还可以将 unknown enum 反序列化为一个默认值

只需要修改配置:

public class JsonUtil {
    private static ObjectMapper mapper;
    static {
        mapper = new ObjectMapper();
        // ...
        // unknown enum -> default
        mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true);
    }
}  

然后加上@JsonEnumDefaultValue 注解,

public enum RateSpan {
    // ...
    // 加上default注解
    @JsonEnumDefaultValue
    Y01("近一年"), Y03("近三年"),
    // ...
}

单元测试。FUCK反序列化为 默认的 Y01:

class RateSpanTest {
    @Test void deserialize() throws JsonProcessingException {
        RateSpan span = JsonUtil.loadStr("\"Y01\"", RateSpan.class);
        assertEquals(span, RateSpan.Y01);
        
        // "FUCK" -> Y01
        span = JsonUtil.loadStr("\"FUCK\"", RateSpan.class);
        assertEquals(span, RateSpan.Y01);
    }
}

骚铭科技
1 声望2 粉丝

条路自己行,扑街唔好喊


« 上一篇
初探Groovy