zoukankan      html  css  js  c++  java
  • jackson JsonPropertyOrder和@JsonIgnoreProperties注解

    有些时候,我们在和外部系统交互的时候使用了json作为标准的数据交换格式,同时为了安全性考虑,增加了对报文的校验,因此我们需要确保序列化的时候参数有序且不多不少刚好,因为对外的API不像后台和前端交互一样,兼容即可,而是对严谨性的要求极高。jackson默认的机制是序列化的时候,先父类的属性,然后再是子类的属性按照定义的顺序进行(fastjson则刚好相反,先序列化子类,然后序列化父类)。为了使用json的工具类,且达到有序的目的,之前特地研究了fastjson/jackson两者的序列化特性,fastjson/jackson都有设置序列化顺序的参数,也就是jackson @JsonProperty注解的index以及fastjson @JSONField注解的ordinal。实际设置了测试下来,感觉两者都不生效或者有bug,总之行为比较怪异。之前记得jackson有个类级别的@JsonInclude注解可以设置要序列化的所有属性,于是特地测试了,符合预期的要求,不过记错了是JsonIgnoreProperties。结合继承+@JsonFormat注解,我们甚至可以完美的达到对于一个相同的属性比如状态,有些view要称为orderStatus,另外一些称为shippingStatus的目标,同时确保在service/mapper层,完全是场景无关的。jacksonJsonIgnoreProperties/JsonPropertyOrder在序列化和反序列化时仅读取当前类的注解,忽略父类的注解,这样我们就可以做到行为的100%精确控制,同时尽可能的复用了父类的定义。

    如下:

    package tf56.lf.lfoms.model.pub;
    
    import java.io.Serializable;
    import java.util.List;
    
    import javax.validation.constraints.NotNull;
    
    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonPropertyOrder;
    
    import lombok.Getter;
    import lombok.Setter;
    import tf56.lf.base.metadata.validate.ValidServices;
    import tf56.lf.common.util.JacksonHelper;
    import tf56.lf.lfoms.validate.group.Group;
    
    /**
    
     * @author admin
     *
     */
    @Getter
    @Setter
    @Deprecated
    @JsonPropertyOrder({"fromOutPartyType","receiverMobile","sessionBean"})
    @JsonIgnoreProperties({"businessPartId","omsPaymentCollectionList","requestOrderNo"})
    public class TmsCreateRequestOrderIQReqDTO extends TmsCreateRequestOrderMainReqDTO implements Serializable{
    
        private static final long serialVersionUID = 8617922710046163090L;
        
        //费用list
        @ValidServices(services = Group.RQUERSTORDER_CREATE )
        @NotNull
        @JsonFormat
        private List<CreateOmsPaymentCollectionReq> omsPaymentCollectionList;
        
        //货物列表
        @ValidServices(services = Group.RQUERSTORDER_CREATE )
        @NotNull
        private List<CreateGoodsDOReq> goodsList;
        
        public static void main(String[] args) {
            TmsCreateRequestOrderIQReqDTO dto = new TmsCreateRequestOrderIQReqDTO();
            System.out.println(JacksonHelper.toJSON(dto));
        }
    }
    在TmsCreateRequestOrderMainReqDTO类上设置了:

    @JsonPropertyOrder({"sessionBean","fromOutPartyType","receiverMobile"})
    @JsonIgnoreProperties({"senderMobile"})

     输出如下:

    {"fromOutPartyType":null,"receiverMobile":null,"sessionBean":null,"tfSign":null,"senderPartyId":null,"senderName":null,"senderMobile":null,"fromDistrict":null,"fromAddress":null,"senderOrganization":null,"toOutPartyType":null,"receiverPartyId":null,"receiverPartyName":null,"toDistrict":null,"toAddress":null,"receiverOrganization":null,"carriersPartyId":null,"carriersCompany":null,"clientNumber":null,"transportMethod":null,"deliveryMethod":null,"isNeedReceipt":null,"receiptMethod":null,"receiptNum":null,"orderSource":null,"terminal":null,"memo":null,"goodsList":null}

    不过总的来说,Jackson应该提供JsonProperties注解,毕竟仅提供ignore,不提供正向的总会有些时候无法直接满足一样,就像黑白名单一样的道理。

    不过这只是解决了单项的序列化问题,反序列化的时候,同样需要解决。如果暴露的接口直接通过json requestbody映射进来,就只能定义一个一一对应的接口代理类来映射了。

  • 相关阅读:
    从训练数据中随机抽取一打数据的好方法
    黄金坑的说明
    Chainer的初步学习
    split和strip的使用
    转载:configure执行流程(1.5.2)《深入理解Nginx》(陶辉)
    转载:编译安装Nginx(1.5.1)《深入理解Nginx》(陶辉)
    转载:编译安装Nginx(1.4)《深入理解Nginx》(陶辉)
    转载:获取Nginx源码(1.3.5)《深入理解Nginx》(陶辉)
    转载:Linux内核参数的优化(1.3.4)《深入理解Nginx》(陶辉)
    转载:磁盘目录(1.3.3)《深入理解Nginx》(陶辉)
  • 原文地址:https://www.cnblogs.com/zhjh256/p/7295413.html
Copyright © 2011-2022 走看看