• Jackson JSON 序列化 反序列化


    什么是 Jackson ? https://github.com/FasterXML/jackson

    Jackson 主要由以下几个包组成

    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可以反序列化到该对象中。
    使用此模块,可以自动使用单个构造函数类,还支持具有辅助构造函数或静态工厂的类。

    快速开始 -> ObjectMapper

    databind.ObjectMapper 是 Jackson 提供序列化和反序列化的主要的类, 其继承关系 public class ObjectMapper extends ObjectCodec implements Versioned

    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 ->
    $syokaku")
    
    	val ryubi = User("刘备", 38)
    	json = mapper.writeValueAsString(ryubi)
    	println("序列化 $ryubi ->
    $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 方法

    @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 的注解。常用的注解及用法如下。

    @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 的注解

    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,
      "姓名" : "关羽"
    }
    */
    

    属性可见性

    对于一个数据类的属性而言:

    • 若该属性修饰符是 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(?);
    

    https://www.ibm.com/developerworks/cn/java/jackson-advanced-application/index.html

  • 相关阅读:
    动态规划专题选做
    「HZOJ NOIP2020 Round #13」20201127模拟 题解
    「HZOJ NOIP2020 Round #12」20201124模拟 简要题解
    JOI 2019 Final 硬币收藏 第18回日本情報オリンピック 本選 コイン集め 解説
    0202S-SCP 收容记
    NC50993 The XOR Largest Pair 0-1Trie Xor
    LG3120 [USACO15FEB]Cow Hopscotch G CDQ分治维护DP顺序
    2020牛客NOIP赛前集训营-提高组(第二场)
    「HZOJ NOIP2020 Round #5」20201018 模拟
    关于我
  • 原文地址:https://www.cnblogs.com/develon/p/11670924.html
Copyright © 2020-2023  润新知