Jackson常用配置示例


Jackson 提供了 SerializationFeatureDeserializationFeature 来自定义 ObjectMapper 的行为。

对输出缩进

public class MyObject {
  private int intVal;
  private String stringVal;
  private List<String> list;
    .............
}

默认配置下的 JSON 输出是没有缩进的:

MyObject myObject = new MyObject(3, "test String",
List.of("one", "two"));
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(myObject);
System.out.println(s);
{"intVal":3,"stringVal":"test String","list":["one","two"]}

可以用 om.enable(..)om.configure(.., true) 开启缩进或其他功能:

MyObject myObject = new MyObject(3, "test String",
                                 List.of("one", "two"));
ObjectMapper om = new ObjectMapper();

om.enable(SerializationFeature.INDENT_OUTPUT);
// om.configure(SerializationFeature.INDENT_OUTPUT, true);

String s = om.writeValueAsString(myObject);
System.out.println(s);
{
  "intVal" : 3,
  "stringVal" : "test String",
  "list" : [ "one", "two" ]
}

Fail on Unknown Properties

反序列化时,若遇到未知的属性(没有对应的属性,也没有setter 或 handler来处理这样的属性)会抛出异常,

public class MyObject2 {
    private int intVal;

    public MyObject2(int intVal) {
        this.intVal = intVal;
    }

    public MyObject2() {
    }
	...
}

默认会报错:

String jsonSting = "{\"intVal\":3,\"strVal\":\"3\"}";
ObjectMapper om = new ObjectMapper();
System.out.println(jsonSting);
MyObject2 myObject = om.readValue(jsonSting, MyObject2.class);
System.out.println(myObject);
{"intVal":3,"strVal":"3"}
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "strVal" (class org.example.c2.MyObject2), not marked as ignorable (one known property: "intVal"])
 at [Source: (String)"{"intVal":3,"strVal":"3"}"; line: 1, column: 23] (through reference chain: org.example.c2.MyObject2["strVal"])
	at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:987)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1974)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1701)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1679)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:330)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516)
	at org.example.c2.DisableFailOnUnknownProps.disableFailOnUnknownProps2(DisableFailOnUnknownProps.java:49)
	at org.example.c2.DisableFailOnUnknownProps.main(DisableFailOnUnknownProps.java:19)

禁用 DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES

String jsonSting = "{\"intVal\":3,\"strVal\":\"3\"}";

ObjectMapper om = new ObjectMapper();
om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

System.out.println(jsonSting);
MyObject2 myObject = om.readValue(jsonSting, MyObject2.class);
System.out.println(myObject);
{"intVal":3,"strVal":"3"}
MyObject2{intVal=3}

允许序列化空对象

MyEmptyObject 没有可序列化的属性,Jackson 默认的字段属性发现规则:所有被 public 修饰的字段、所有被 public 修饰的getter。没有可序列化的属性时,会抛出异常。

public class MyEmptyObject {
    private int i = 10;
}

默认:

MyEmptyObject myObject = new MyEmptyObject();
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(myObject);
System.out.println(s);
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.example.c2.MyEmptyObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
	at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276)
	at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
	at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71)
	at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
	at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4487)
	at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3742)
	at org.example.c2.DisableFailOnEmptyBeans.defaultOutput(DisableFailOnEmptyBeans.java:24)
	at org.example.c2.DisableFailOnEmptyBeans.main(DisableFailOnEmptyBeans.java:17)

Process finished with exit code 1

禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS

MyEmptyObject myObject = new MyEmptyObject();
ObjectMapper om = new ObjectMapper();
om.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
String s = om.writeValueAsString(myObject);
System.out.println(s);
{}

将空字符串反序列化为 null POJO

默认情况下,空字符串不能反序列化为 null 对象,会抛异常:

String s = "{\"myObjKey\":\"\"}";
System.out.println("input:\n" + s);
ObjectMapper om = new ObjectMapper();
Map<String, MyObject> myObject = om.readValue(s, new TypeReference<Map<String, MyObject>>() { });
System.out.println(myObject);
input:
{"myObjKey":""}
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot coerce empty String ("") to `org.example.c2.MyObject` value (but could if coercion was enabled using `CoercionConfig`)
 at [Source: (String)"{"myObjKey":""}"; line: 1, column: 13] (through reference chain: java.util.LinkedHashMap["myObjKey"])
	at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.reportBadCoercion(DeserializationContext.java:1666)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._checkCoercionFail(StdDeserializer.java:1432)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromEmptyString(StdDeserializer.java:325)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromString(StdDeserializer.java:270)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1495)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:207)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:197)
	at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:609)
	at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:437)
	at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:32)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3531)
	at org.example.c2.EnableEmptyStringAsNullPojo.defaultOutput(EnableEmptyStringAsNullPojo.java:25)
	at org.example.c2.EnableEmptyStringAsNullPojo.main(EnableEmptyStringAsNullPojo.java:17)

Process finished with exit code 1

启用 DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,此设置只能用于 POJO 或一些结构化的值(比如 java.util.Mapsjava.util.Collection),但不能用于标量值(scalar values ,比如 boolean 和 number),是否可以强制使用它们取决于 MapperFeature.ALLOW_COERCION_OF_SCALARS

String s = "{\"myObjKey\":\"\"}";
System.out.println("input:\n" + s);
ObjectMapper om = new ObjectMapper();
om.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
Map<String, MyObject> myObject = om.readValue(s, new TypeReference<Map<String, MyObject>>() { });
System.out.println(myObject);
input:
{"myObjKey":""}
{myObjKey=null}

空字符串与 Java simple objects

Java simple objects 不受 DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT 的控制。

BigDecimal

String s = "{\"myObjKey\":\"\"}";
System.out.println("input:\n " + s);
ObjectMapper om = new ObjectMapper();
Map<String, BigDecimal> myObject = om.readValue(s,
new TypeReference<Map<String, BigDecimal>>() { });
System.out.println(myObject);
input:
 {"myObjKey":""}
{myObjKey=null}

String

String s = "{\"myObjKey\":\"\"}";
System.out.println("input:\n " + s);

ObjectMapper om = new ObjectMapper();
Map<String, String> myObject = om.readValue(s,
new TypeReference<Map<String, String>>() { });
System.out.println(myObject);
input:
 {"myObjKey":""}
{myObjKey=}

序列化时的时间格式化

默认情况下,时间会以时间戳的形式序列化:

Date date = new Date();
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(Map.of("myDate", date));
System.out.println(s);
{"myDate":1618323884853}

禁用 SerializationFeature.WRITE_DATES_AS_TIMESTAMPS

Date date = new Date();
ObjectMapper om = new ObjectMapper();
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
String s = om.writeValueAsString(Map.of("myDate", date));
System.out.println(s);
{"myDate":"2021-04-13T14:24:45.061+00:00"}

原文链接

Jackson JSON - Jackson Commonly used Configuration Examples

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值