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映射進來,就只能定義一個一一對應的接口代理類來映射了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM