记录一次FastJSON反序列化异常解决方案(内部类反序列化失败问题)

1,211 阅读4分钟

说明

使用FastJSON通过嵌套内部类解析json数据造成的错误

错误信息

Caused by: java.lang.IllegalArgumentException: argument type mismatch

详细信息

com.alibaba.fastjson.JSONException: create instance error
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:276)
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:845)
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:300)
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:296)
at com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer.parseField(DefaultFieldDeserializer.java:86)
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:857)
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:300)
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:296)
at com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer.parseField(DefaultFieldDeserializer.java:86)
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:857)
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:300)
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:698)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:395)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:299)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:572)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:271)
        ... 42 more

错误代码

import lombok.Data;

import java.util.ArrayList;

@Data
public class RecordDetailModel {

    private String serialNumber;

    private String deviceType;

    private Boolean isDilution;

    private Double dilutionValue;

    private Diagnose diagnose;

    private Item item;

    private Card card;

    @Data
    public class Diagnose{

        private String lastMensesDate;

        private Integer menstrualCycleDays;

        private String nextMeasureBeginTime;

        private String nextMeasureEndTime;

        private String conclusion;

        private String conclusionId;

        private String conclusionTip;

        private String physiologicalCycle;

        private String physiologicalCycleDesc;

        private String ovulationStage;

        private String ovulationStageDesc;

        private String ovulationBeginTime;

        private String ovulationEndTime;

        private String pregnantRate;

        private String pregnantRateDesc;

        private String poaBeginTime;

        private String peakDetectedTime;

        private String peakReduceDetectedTime;

        private Integer diagnoseStatus;

        private String follicleStage;

        private String follicleStageDesc;

        private Double resultValue;

        private Double lastResultValue;

        private Integer minPregnancyWeek;

        private Integer maxPregnancyWeek;

        private Integer pregnancyWeekDay;

        private String resultGrowthPercent;

        private String pregnantState;

        private String pregnantStateDesc;

    }

    @Data
    public class Item{

        private Integer itemId;

        private String itemType;

        private String itemName;

    }

    @Data
    public class Card{

        private Integer cardId;

        private Integer cardName;

        private String cardType;

        private ArrayList<Index> indexList;

    }

    @Data
    public class Index{

        private Integer resultId;

        private Integer indexId;

        private String indexName;

        private String lineType;

        private Double resultValue;

        /**
         * 检测结果状态:0-无结论,1-未超标,2-超标,3-检出,4-
         * 未检出,5-超出检出,6-阴性,7-阳性,8-可疑(比色),9-可
         * 疑(无国标)
         */
        private Integer resultStatus;

        private String resultDesc;

        private String thicknessUnit;

        private Integer diagnoseType;

        private Boolean useGrade;

        private Integer standardType;

        private Double maxThickness;

        private Double minThickness;

        private Double maxThicknessUp;

        private Double minThicknessLow;

        private Double nationStand;

        private Double maxNationStand;

        private Double minNationStand;

        private Double maxNegative;

        private Double minPositive;

        private Double createTime;

    }

测试代码

JSON.parseObject(json数据, RecordDetailModel.class);

解决方案

1.使用静态内部类

import lombok.Data;

import java.util.ArrayList;

@Data
public class RecordDetailModel {

    private String serialNumber;

    private String deviceType;

    private Boolean isDilution;

    private Double dilutionValue;

    private Diagnose diagnose;

    private Item item;

    private Card card;

    @Data
    public static class Diagnose{

        private String lastMensesDate;

        private Integer menstrualCycleDays;

        private String nextMeasureBeginTime;

        private String nextMeasureEndTime;

        private String conclusion;

        private String conclusionId;

        private String conclusionTip;

        private String physiologicalCycle;

        private String physiologicalCycleDesc;

        private String ovulationStage;

        private String ovulationStageDesc;

        private String ovulationBeginTime;

        private String ovulationEndTime;

        private String pregnantRate;

        private String pregnantRateDesc;

        private String poaBeginTime;

        private String peakDetectedTime;

        private String peakReduceDetectedTime;

        private Integer diagnoseStatus;

        private String follicleStage;

        private String follicleStageDesc;

        private Double resultValue;

        private Double lastResultValue;

        private Integer minPregnancyWeek;

        private Integer maxPregnancyWeek;

        private Integer pregnancyWeekDay;

        private String resultGrowthPercent;

        private String pregnantState;

        private String pregnantStateDesc;

    }

    @Data
    public static class Item{

        private Integer itemId;

        private String itemType;

        private String itemName;

    }

    @Data
    public static class Card{

        private Integer cardId;

        private String cardName;

        private String cardType;

        private ArrayList<Index> indexList;

    }

    @Data
    public static class Index{

        private Integer resultId;

        private Integer indexId;

        private String indexName;

        private String lineType;

        private Double resultValue;

        /**
         * 检测结果状态:0-无结论,1-未超标,2-超标,3-检出,4-
         * 未检出,5-超出检出,6-阴性,7-阳性,8-可疑(比色),9-可
         * 疑(无国标)
         */
        private Integer resultStatus;

        private String resultDesc;

        private String thicknessUnit;

        private Integer diagnoseType;

        private Boolean useGrade;

        private Integer standardType;

        private Double maxThickness;

        private Double minThickness;

        private Double maxThicknessUp;

        private Double minThicknessLow;

        private Double nationStand;

        private Double maxNationStand;

        private Double minNationStand;

        private Double maxNegative;

        private Double minPositive;

        private String createTime;

    }

}

2.将内部类定义在同级(或定义为单独的java文件)

import lombok.Data;

import java.util.ArrayList;

@Data
public class RecordDetailModel {

    private String serialNumber;

    private String deviceType;

    private Boolean isDilution;

    private Double dilutionValue;

    private Diagnose diagnose;

    private Item item;

    private Card card;

}

@Data
class Diagnose{

    private String lastMensesDate;

    private Integer menstrualCycleDays;

    private String nextMeasureBeginTime;

    private String nextMeasureEndTime;

    private String conclusion;

    private String conclusionId;

    private String conclusionTip;

    private String physiologicalCycle;

    private String physiologicalCycleDesc;

    private String ovulationStage;

    private String ovulationStageDesc;

    private String ovulationBeginTime;

    private String ovulationEndTime;

    private String pregnantRate;

    private String pregnantRateDesc;

    private String poaBeginTime;

    private String peakDetectedTime;

    private String peakReduceDetectedTime;

    private Integer diagnoseStatus;

    private String follicleStage;

    private String follicleStageDesc;

    private Double resultValue;

    private Double lastResultValue;

    private Integer minPregnancyWeek;

    private Integer maxPregnancyWeek;

    private Integer pregnancyWeekDay;

    private String resultGrowthPercent;

    private String pregnantState;

    private String pregnantStateDesc;

}

@Data
class Item{

    private Integer itemId;

    private String itemType;

    private String itemName;

}

@Data
class Card{

    private Integer cardId;

    private Integer cardName;

    private String cardType;

    private ArrayList<Index> indexList;

}

@Data
class Index{

    private Integer resultId;

    private Integer indexId;

    private String indexName;

    private String lineType;

    private Double resultValue;

    /**
     * 检测结果状态:0-无结论,1-未超标,2-超标,3-检出,4-
     * 未检出,5-超出检出,6-阴性,7-阳性,8-可疑(比色),9-可
     * 疑(无国标)
     */
    private Integer resultStatus;

    private String resultDesc;

    private String thicknessUnit;

    private Integer diagnoseType;

    private Boolean useGrade;

    private Integer standardType;

    private Double maxThickness;

    private Double minThickness;

    private Double maxThicknessUp;

    private Double minThicknessLow;

    private Double nationStand;

    private Double maxNationStand;

    private Double minNationStand;

    private Double maxNegative;

    private Double minPositive;

    private Double createTime;

}

3.嵌套内部类

import lombok.Data;

import java.util.ArrayList;

@Data
public class RecordDetailModel {

    private String serialNumber;

    private String deviceType;

    private Boolean isDilution;

    private Double dilutionValue;

    private Diagnose diagnose;

    private Item item;

    private Card card;

    @Data
    public class Diagnose{

        private String lastMensesDate;

        private Integer menstrualCycleDays;

        private String nextMeasureBeginTime;

        private String nextMeasureEndTime;

        private String conclusion;

        private String conclusionId;

        private String conclusionTip;

        private String physiologicalCycle;

        private String physiologicalCycleDesc;

        private String ovulationStage;

        private String ovulationStageDesc;

        private String ovulationBeginTime;

        private String ovulationEndTime;

        private String pregnantRate;

        private String pregnantRateDesc;

        private String poaBeginTime;

        private String peakDetectedTime;

        private String peakReduceDetectedTime;

        private Integer diagnoseStatus;

        private String follicleStage;

        private String follicleStageDesc;

        private Double resultValue;

        private Double lastResultValue;

        private Integer minPregnancyWeek;

        private Integer maxPregnancyWeek;

        private Integer pregnancyWeekDay;

        private String resultGrowthPercent;

        private String pregnantState;

        private String pregnantStateDesc;

    }

    @Data
    public class Item{

        private Integer itemId;

        private String itemType;

        private String itemName;

    }

    @Data
    public class Card{

        private Integer cardId;

        private Integer cardName;

        private String cardType;

        private ArrayList<Index> indexList;

        @Data
        public class Index{

            private Integer resultId;

            private Integer indexId;

            private String indexName;

            private String lineType;

            private Double resultValue;

            /**
             * 检测结果状态:0-无结论,1-未超标,2-超标,3-检出,4-
             * 未检出,5-超出检出,6-阴性,7-阳性,8-可疑(比色),9-可
             * 疑(无国标)
             */
            private Integer resultStatus;

            private String resultDesc;

            private String thicknessUnit;

            private Integer diagnoseType;

            private Boolean useGrade;

            private Integer standardType;

            private Double maxThickness;

            private Double minThickness;

            private Double maxThicknessUp;

            private Double minThicknessLow;

            private Double nationStand;

            private Double maxNationStand;

            private Double minNationStand;

            private Double maxNegative;

            private Double minPositive;

            private Double createTime;

        }

    }

}