zoukankan      html  css  js  c++  java
  • Jackson 序列化/反序列化时忽略某属性

    基于Spring MVC的RESTful接口基本都使用了Jackson这个类库。

    使用过程中总会有
    1. 序列化时忽略某属性(如Password)
    2. 反序列化时忽略某属性(如HashedPassword)

    其实对应在Bean中,就是类的Setter/Getter方法。

    Jackson提供了@Jsonignore这个注解,用于在(反)序列化时,忽略bean的某项属性。在Jackson 1.9的时候,@Jsonignore的语义还有了变化,如下:

    1.9之前:
    在Setter方法上加@Jsonignore注解并不会影响Getter方法的调用

    1.9之后:
    在Setter方法上加@Jsonignore会导致整个这个属性在序列化过程中被忽略。
    https://stackoverflow.com/questions/12505141/only-using-jsonignore-during-serialization-but-not-deserialization

    所以在1.9之后需要使用其他的方法来设置某个属性是否需要(反)序列化:
    Java代码  收藏代码
    1. @JsonProperty(access = Access.WRITE_ONLY)  


    通过设置JsonProperty的access属性来确定当前属性是不是需要自动序列化/反序列化。

    WRITE_ONLY:仅做反序列化操作。
    READ_ONLY:仅做序列化操作。

    现在的问题是,2.8.7版本的jackson databind (start.spring.io在引入Spring-Web-Starter时候自动引入的,版本是Spring Boot 1.5.X-RELEASE), 在使用READ_ONLY时,并没有忽略反序列化操作,查询了一下应该是jackson databind的一个bug:
    https://github.com/FasterXML/jackson-databind/issues/95
    https://github.com/FasterXML/jackson-databind/issues/935
    尽管bug已经关闭,但是似乎还是有问题,这时候有以下Work around在935中有提到:

    Java代码  收藏代码
    1. @JsonIgnoreProperties(value="some_field", allowGetters = true, allowSetters = false)  

    在类上加上以上注解,工作正常。

    注:并未完美解决,似乎JsonIgnoreProperties和JsonIgnore不能共存,这样的话如果某个类既有屏蔽get方法也有屏蔽set方法的话就不知道怎么搞了
    另外 https://github.com/FasterXML/jackson-databind/issues/1805 是个比较新的相关bug 跟踪一下。

    更新,已经查到问题,由于jackson在处理collection和map时会自动USE_GETTERS_AS_SETTERS,所以会产生问题,引用自己在github的comment:

    引用
    wwwcomy commented 4 minutes ago • edited
    Facing the same problem, in issue #935, seems only simple types were handled correctly.

    I looked into the code, the issue was caused by some special logic for USE_GETTERS_AS_SETTERS, in BeanDeserializerFactory Line 565 (version 2.8.10):

    Java代码  收藏代码
    1. if (propDef.hasSetter()) {  
    2.                 JavaType propertyType = propDef.getSetter().getParameterType(0);  
    3.                 prop = constructSettableProperty(ctxt, beanDesc, propDef, propertyType);  
    4.             } else if (propDef.hasField()) {  
    5.                 JavaType propertyType = propDef.getField().getType();  
    6.                 prop = constructSettableProperty(ctxt, beanDesc, propDef, propertyType);  
    7.             } else if (useGettersAsSetters && propDef.hasGetter()) {  
    8.                 /* May also need to consider getters 
    9.                  * for Map/Collection properties; but with lowest precedence 
    10.                  */  
    11.                 AnnotatedMethod getter = propDef.getGetter();  
    12.                 // should only consider Collections and Maps, for now?  
    13.                 Class<?> rawPropertyType = getter.getRawType();  
    14.                 if (Collection.class.isAssignableFrom(rawPropertyType)  
    15.                         || Map.class.isAssignableFrom(rawPropertyType)) {  
    16.                     prop = constructSetterlessProperty(ctxt, beanDesc, propDef);  
    17.                 }  
    18.             }  

    By default USE_GETTERS_AS_SETTERS is enabled, so, although the Collection member was defined Access as "READ_ONLY", still, it is set as a property in the builder instance.

    My work around is using (for spring boot applications) spring.jackson.mapper.USE_GETTERS_AS_SETTERS=false

    However, I'm not sure this behavior is a bug or not, @cowtowncoder please help to clarify.
  • 相关阅读:
    MISRA C:2012 8 Rules 8.1 A Standard C environment
    《程序设计与算法(二)算法基础》《第二周 递归》爬楼梯 4017
    关于extern "C"(详细剖析)
    Github与TortoiseGit关联
    《程序设计与算法(二)算法基础》《第二周 递归》四则运算表达式求值 4132
    c语言 宏
    MISRA C:2012 Dir-1.1(Required)
    《程序设计与算法(二)算法基础》《第二周 递归》逆波兰表达式
    cogs1619. [HEOI2012]采花 x
    cogs157. [USACO Nov07] 奶牛跨栏 x
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/11978638.html
Copyright © 2011-2022 走看看