Jackson是spring-boot-starter-json的一部分,spring-boot-starter-web中包含spring-boot-starter-json。也就是说,当项目中引入spring-boot-starter-web后会自动引入spring-boot-starter-json。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
ObjectMapper
ObjectMapper是jackson-databind包中的一个类,提供读写JSON的功能,可以方便的进行对象和JSON转换:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
public final class JsonUtil {
private static ObjectMapper mapper = new ObjectMapper();
private JsonUtil() {
}
/**
* Serialize any Java value as a String.
*/
public static String generate(Object object) throws JsonProcessingException {
return mapper.writeValueAsString(object);
}
/**
* Deserialize JSON content from given JSON content String.
*/
public static <T> T parse(String content, Class<T> valueType) throws IOException {
return mapper.readValue(content, valueType);
}
}
编写一简单POJO测试类:
import java.util.Date;
public class Hero {
public static void main(String[] args) throws Exception {
System.out.println(JsonUtil.generate(new Hero("Jason", new Date())));
}
private String name;
private Date birthday;
public Hero(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
public String getName() {
return name;
}
public Date getBirthday() {
return birthday;
}
}
运行后输出结果如下:
{"name":"Jason","birthday":1540909420353}
可以看到日期转换为长整型。
ObjectMapper默认序列化配置启用了SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,日期将转换为长整型。可查看如下源码:
public ObjectMapper(JsonFactory jf, DefaultSerializerProvider sp, DefaultDeserializationContext dc) {
...
BaseSettings base = DEFAULT_BASE.withClassIntrospector(defaultClassIntrospector());
_configOverrides = new ConfigOverrides();
_serializationConfig = new SerializationConfig(base, _subtypeResolver, mixins, rootNames, _configOverrides);
...
}
public SerializationConfig(BaseSettings base, SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames,
ConfigOverrides configOverrides)
{
super(base, str, mixins, rootNames, configOverrides);
_serFeatures = collectFeatureDefaults(SerializationFeature.class);
_filterProvider = null;
_defaultPrettyPrinter = DEFAULT_PRETTY_PRINTER;
_generatorFeatures = 0;
_generatorFeaturesToChange = 0;
_formatWriteFeatures = 0;
_formatWriteFeaturesToChange = 0;
}
默认情况下,将调用DateSerializer的_timestamp 方法:
/**
* For efficiency, we will serialize Dates as longs, instead of
* potentially more readable Strings.
*/
@JacksonStdImpl
@SuppressWarnings("serial")
public class DateSerializer extends DateTimeSerializerBase<Date> {
...
@Override
protected long _timestamp(Date value) {
return (value == null) ? 0L : value.getTime();
}
@Override
public void serialize(Date value, JsonGenerator g, SerializerProvider provider) throws IOException {
if (_asTimestamp(provider)) {
g.writeNumber(_timestamp(value));
return;
}
_serializeAsString(value, g, provider);
}
}
DateTimeSerializerBase的_asTimestamp方法:
protected boolean _asTimestamp(SerializerProvider serializers)
{
if (_useTimestamp != null) {
return _useTimestamp.booleanValue();
}
if (_customFormat == null) {
if (serializers != null) {
return serializers.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
// 12-Jun-2014, tatu: Is it legal not to have provider? Was NPE:ing earlier so leave a check
throw new IllegalArgumentException("Null SerializerProvider passed for "+handledType().getName());
}
return false;
}
待续....