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
    评论
在SpringMVC中,可以使用Jackson框架来将Java对象或集合转换成JSON类型的字符串。Jackson是一个常用JSON解析和序列化框架,支持Java对象和JSON数据的互相转换。 手动将Java对象或集合转换成JSON类型的字符串可以使用Jackson提供的ObjectMapper类的writeValueAsString()方法,示例如下: ```java import com.fasterxml.jackson.databind.ObjectMapper; ObjectMapper objectMapper = new ObjectMapper(); String jsonString = objectMapper.writeValueAsString(myObject); ``` 其中,myObject为需要转换的Java对象。 在SpringMVC中,配置JSON类型转换可以通过添加Jackson相关的依赖和配置Spring的消息转换器实现。具体步骤如下: 1. 添加Jackson相关的依赖,如下所示: ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> ``` 2. 在Spring配置文件中配置消息转换器,如下所示: ```xml <mvc:annotation-driven> <mvc:message-converters> <!-- JSON消息转换器 --> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="com.fasterxml.jackson.databind.ObjectMapper"> <property name="serializationInclusion" value="NON_NULL" /> <property name="dateFormat"> <bean class="java.text.SimpleDateFormat"> <constructor-arg value="yyyy-MM-dd HH:mm:ss" /> </bean> </property> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> ``` 其中,MappingJackson2HttpMessageConverter是Spring提供的JSON消息转换器,objectMapper属性配置Jackson的ObjectMapper对象,可以设置序列化的规则,如是否输出null值、时间格式等。在SpringMVC处理请求时,会根据请求头中的Content-Type自动选择对应的消息转换器,从而实现请求和响应数据的自动转换。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值