Jackson--反序列化的解析


項目中經常需要調用指定服務的接口,並且對返回的json結果數據,進行反序列化生成java類。

若是返回的數據格式固定,那么直接按照固定的格式進行反序列化生成java類便可。但是由於

返回的結果數據格式不固定,需要自己編寫反序列化類進行分析。

下面我講展示下項目中遇到的情況。

 

{

    "status": "200",

    "Goal": {

        "userId": "17090016",

        "templateId": "26",

        "templateName": "測試-營銷通用目標模板",

        "performance": [

            {

                "id": "8022",

                "indexCode": "",

                "name": "執行績效綜合達成率",

                "category": "New Category",

                "categoryName": "執行績效",

                "start": "2019-10-01T00:00:00.000",

                "due": "2019-10-31T00:00:00.000",

                "bizxTarget": "",

                "bizxActual": "",

                "done": "0.0",

                "higedone": "",

                "stateLabel": "重大延遲",

                "weight": "",

                "dataSource": "",

                "lastModified": "2019-12-11T08:45:47.000",

                "modifier": "17090016",

                "children": ""

            },
            {

                "id": "8015",

                "indexCode": "",

                "name": "協訪達成率",

                "category": "Goals",

                "categoryName": "先決條件",

                "start": "2019-10-01T00:00:00.000",

                "due": "2019-10-31T00:00:00.000",

                "bizxTarget": "47.0",

                "bizxActual": "73.0",

                "done": "0.0",

                "higedone": "100.0",

                "stateLabel": "重大延遲",

                "weight": "",

                "dataSource": "手持",

                "lastModified": "2019-12-11T13:57:09.000",

                "modifier": "17090016",

                "children": 
                    {

                        "childDescription": "CS協訪",

                        "childTarget": "15",

                        "childActual": "18",

                        "childDone": "100.0"

                    }

            },


            {

                "id": "8017",

                "indexCode": "",

                "name": "分銷達成率",

                "category": "New Category",

                "categoryName": "執行績效",

                "start": "2019-10-01T00:00:00.000",

                "due": "2019-10-31T00:00:00.000",

                "bizxTarget": "100.0",

                "bizxActual": "23.39",

                "done": "23.39",

                "higedone": "100.0",

                "stateLabel": "重大延遲",

                "weight": "20.0",

                "dataSource": "訂單管理",

                "lastModified": "2019-12-11T14:09:32.000",

                "modifier": "17090016",

                "children": [

                    {

                        "childDescription": "門店數",

                        "childTarget": "",

                        "childActual": "23",

                        "childDone": ""

                    },

                    {

                        "childDescription": "門店品類數",

                        "childTarget": "",

                        "childActual": "31",

                        "childDone": ""

                    },

                    {

                        "childDescription": "門店SKU",

                        "childTarget": "",

                        "childActual": "25",

                        "childDone": ""

                    }

                ]

            }
}

上面的json格式數據中,其余的字段格式都是比較的固定,但是可以看到children的數據內容出現了3種:
1、字符串內容
2、對象
3、數組
由於children的內容格式不固定,則直接利用jackson進行反序列化會失敗,所以需要我們自己編寫反序列化的實現類。
但是只是children的內容格式不固定,我們只是需要對children編寫反序列化的實現類。
代碼如下;

整個json對應的javabean
package com.shinho.plrs.front.pojo;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

@Data
@ApiModel("指標")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Target {

    @ApiModelProperty("id")
    String id;

    @ApiModelProperty("指標編碼")
    String code;

    @JsonGetter("code")
    public String getCode() {
        return this.code;
    }

    @JsonSetter(value = "indexCode")
    public void setCode(String code) {
        this.code = code;
    }

    @ApiModelProperty("指標名稱")
    String purpose;

    @ApiModelProperty("指標類型編碼")
    String category;

    @ApiModelProperty("指標類型名稱")
    String categoryName;

    @JsonProperty("start")
    @ApiModelProperty("開始日期")
    String startDate;

    @JsonProperty("due")
    @ApiModelProperty("結束日期")
    String endDate;

    @ApiModelProperty("目標")
    String aim;

    @ApiModelProperty("實際")
    String acture;

    @ApiModelProperty("達成率")
    String done;

    @ApiModelProperty("達成率封頂值")
    String higedone;

    @ApiModelProperty("狀態(文本)")
    String stateLabel;

    @ApiModelProperty("權重")
    String weight;

    @ApiModelProperty("數據來源")
    String dataSource;

    @ApiModelProperty("最近修改時間")
    String lastModified;

    @ApiModelProperty("修改人")
    String modifier;

//    @ApiModelProperty("子指標數據")
//    List<Child> childs = new ArrayList<>();

    @ApiModelProperty("子指標數據")
    @JsonDeserialize(using = ChildrenDeserializer.class)
    List<Child> children;
}

package com.shinho.plrs.front.pojo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@ApiModel("子指標")
@Accessors(chain = true)
public class Child {

    @ApiModelProperty("子指標描述")
    String childDescription;

    @ApiModelProperty("子指標目標")
    String childTarget;

    @ApiModelProperty("子指標完成值")
    String childActual;

    @ApiModelProperty("子指標達成率")
    String childDone;


}

 

反序列化類的實現:

 
package com.shinho.plrs.front.pojo;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ChildrenDeserializer extends StdDeserializer<List<Child>> {

    public ChildrenDeserializer() {
        super(List.class);
    }

    public ChildrenDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public List<Child> deserialize(JsonParser parser, DeserializationContext deserializer) throws IOException {
        List<Child> list = new ArrayList<>();
        if (StringUtils.isEmpty(parser.getText())) return list;
        if (JsonToken.START_ARRAY.equals(parser.getCurrentToken())) {
            while (!JsonToken.END_ARRAY.equals(parser.getCurrentToken())) {
                list.add(parseJsonObjectToChild(parser));
                parser.nextToken();
            }
        } else if (JsonToken.START_OBJECT.equals(parser.getCurrentToken())) {
            list.add(parseJsonObjectToChild(parser));
        }
        return list;
    }

    /**
     * 將json數據分析成java對象
     *
     * @param parser
     * @return
     */
    private Child parseJsonObjectToChild(JsonParser parser) throws IOException {
        Child child = new Child();
        JsonToken token = parser.getCurrentToken();
        String fieldName = null;
        while (!JsonToken.END_OBJECT.equals(token)) {
            if (!JsonToken.FIELD_NAME.equals(token)) {
                token = parser.nextToken();
                continue;
            }
            fieldName = parser.getCurrentName();
            token = parser.nextToken();
            try {
                BeanUtils.getPropertyDescriptor(Child.class, fieldName).getWriteMethod().invoke(child, parser.getText());
                token = parser.nextToken();
            } catch (Exception e) {
                log.error("反序列化child過程中,出現異常:", e);
            }
        }
        return child;
    }


}
 
         

 

 

 


免責聲明!

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



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