什么是 Jackson ? https://github.com/FasterXML/jackson
Jackson 主要由如下几个包组成html
1. Jackson Databind 数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API 2. Jackson Core 核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是经过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json 3. Jackson Annotations 注解包,提供标准注解功能
Kotlin 插件 -- jackson-module-kotlin https://github.com/FasterXML/jackson-module-kotlin
该模块增长了对Kotlin类和数据类的序列化/反序列化的支持。 Jackson的附加模块,用于支持Kotlin语言,特别是方法/构造函数参数名称的自省,而无需添加显式的属性名称注释。 该模块增长了对Kotlin类和数据类的序列化/反序列化的支持。之前,必须在Kotlin对象上存在默认构造函数,以便Jackson能够反序列化到该对象中。 使用此模块,能够自动使用单个构造函数类,还支持具备辅助构造函数或静态工厂的类。java
快速开始 -> ObjectMapper
databind.ObjectMapper
是 Jackson 提供序列化和反序列化的主要的类, 其继承关系 public class ObjectMapper extends ObjectCodec implements Versioned
git
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.SerializationFeature data class User(val name: String = "Unknown", val age: Int = 0) var mapper = ObjectMapper() fun main(args: Array<String>) { usage() mapper.enable(SerializationFeature.INDENT_OUTPUT) // 应用缩进, 加强可读性 usage() } fun usage() { var json = """{"name":"诸葛孔明"}""" val syokaku = mapper.readValue(json, User::class.java) println("反序列化 $json ->\n$syokaku") val ryubi = User("刘备", 38) json = mapper.writeValueAsString(ryubi) println("序列化 $ryubi ->\n$json") } /* 反序列化 {"name":"诸葛孔明"} -> User(name=诸葛孔明, age=0) 序列化 User(name=刘备, age=38) -> {"name":"刘备","age":38} 反序列化 {"name":"诸葛孔明"} -> User(name=诸葛孔明, age=0) 序列化 User(name=刘备, age=38) -> { "name" : "刘备", "age" : 38 } */
SerializationFeature DeserializationFeature
(反)序列化枚举,定义了简单的开/关功能,这些功能影响Java对象的(反)序列化方式
ObjectMapper#enable(SerializationFeature.INDENT_OUTPUT) 等价于 ObjectMapper#configure(SerializationFeature.INDENT_OUTPUT, ture) ObjectMapper#configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) // 反序列化时忽略多余的Java类不存在的字段 ObjectMapper#configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false) //在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ ObjectMapper#setSerializationInclusion(Include.NON_NULL); //在序列化时忽略值为 null 的属性 ObjectMapper#setDefaultPropertyInclusion(Include.NON_DEFAULT); //忽略值为默认值的属性
如何配置 Spring 中的 ObjectMapper 呢? MappingJackson2HttpMessageConverter 提供了 getter 方法github
@Configuration @EnableWebMvc open class ServletConfig : WebMvcConfigurer { override fun configureContentNegotiation(configurer: ContentNegotiationConfigurer) { configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8) } override fun configureDefaultServletHandling(configurer: DefaultServletHandlerConfigurer) { global.log("Spring MVC就绪") configurer.enable() // MVC未映射的请求交由容器提供的默认Servlet来处理 } override fun configureMessageConverters(converters: MutableList<HttpMessageConverter<*>>) { val stringmc = StringHttpMessageConverter(Charsets.UTF_8) stringmc.setWriteAcceptCharset(false) converters.add(stringmc) val jsonmc = MappingJackson2HttpMessageConverter() val mapper = jsonmc.getObjectMapper() mapper.configure(SerializationFeature.INDENT_OUTPUT, true) mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) converters.add(jsonmc) global.log("消息转换器就绪") } }
注解
Jackson 根据它的默认方式序列化和反序列化 java 对象,若根据实际须要,灵活的调整它的默认方式,能够使用 Jackson 的注解。经常使用的注解及用法以下。json
@JsonProperty 用于属性,把属性的名称序列化时转换为另一个名称。示例: @JsonProperty("birth_ date") private Date birthDate; @JsonFormat 用于属性或者方法,把属性的格式序列化时转换成指定的格式。示例: @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm") public Date getBirthDate() @JsonPropertyOrder 用于类, 指定属性在序列化时 json 中的顺序 , 示例: @JsonPropertyOrder({ "birth_Date", "name" }) public class Person @JsonCreator 用于构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法。 示例: @JsonCreator public Person(@JsonProperty("name")String name) {…} @JsonAnySetter 用于属性或者方法,设置未反序列化的属性名和值做为键值存储到 map 中 @JsonAnySetter public void set(String key, Object value) { map.put(key, value); } @JsonAnyGetter 用于方法 ,获取全部未序列化的属性 public Map<String, Object> any() { return map; }
注意, Kotlin 如何从构造方法中指定 Field 的注解app
data class User(@field:JsonProperty("姓名") var name: String = "Unknown", val age: Int = 0) fun usage() { val user = mapper.readValue("""{"姓名":"关羽"}""", User::class.java) println(user) println(mapper.writeValueAsString(user)) } /* User(name=关羽, age=0) { "age" : 0, "姓名" : "关羽" } */
属性可见性
对于一个数据类的属性而言:ide
- 若该属性修饰符是 public,该属性可序列化和反序列化。
- 若属性的修饰符不是 public,可是它的 getter 方法和 setter 方法是 public,该属性可序列化和反序列化。由于 getter 方法用于序列化, 而 setter 方法用于反序列化。
- 若属性只有 public 的 setter 方法,而无 public 的 getter 方 法,该属性只能用于反序列化。
若想更改默认的属性可视化的规则,须要调用 ObjectMapper 的方法 setVisibility。函数
ObjectMapper#setVisibility(PropertyAccessor.FIELD, Visibility.ANY); PropertyAccessor 支持的类型有 ALL,CREATOR,FIELD,GETTER,IS_GETTER,NONE,SETTER Visibility 支持的类型有 ANY,DEFAULT,NON_PRIVATE,NONE,PROTECTED_AND_PUBLIC,PUBLIC_ONLY
属性过滤
经过属性过滤能够屏蔽隐私属性, 属性过滤有多种实现方式性能
- 注解
// 从 getter 方法屏蔽 @JsonIgnore public int getAge() // 从 class 屏蔽 @JsonIgnoreProperties(value = { "age","birth_date" }) public class Person
- addMixIn 方法加注解方式@JsonIgnoreProperties ?
- SimpleBeanPropertyFilter 方式 ?
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("myFilter", newFilter); mapper.setFilterProvider(filterProvider).writeValueAsString(?);
<hr> https://www.ibm.com/developerworks/cn/java/jackson-advanced-application/index.htmlurl