最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

抽象類使用Jackson序列化問題

 更新時(shí)間:2023年01月01日 08:24:38   作者:追夢(mèng)菜鳥  
這篇文章主要介紹了抽象類使用Jackson序列化問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

抽象類使用Jackson序列化

當(dāng)java對(duì)象中含List<Object>時(shí),如果Object一個(gè)抽象類或接口,這里就會(huì)出現(xiàn)java多態(tài)的現(xiàn)象,比如List<Animal>, 如果Animal是個(gè)抽象類,并且有多個(gè)子類時(shí),由于List中保存的Animal沒有明確指向具體的子類或?qū)崿F(xiàn)類,json反序列化java對(duì)象時(shí)就會(huì)拋出提示:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException:Can not construct instance of Animal, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information

可以使用@JsonTypeInfo與@JsonSubTypes來解決此類問題,通過注解,可以在序列化時(shí),保存具體的類型信息到j(luò)son中,當(dāng)json反序列到j(luò)ava對(duì)象時(shí),就可以根據(jù)具體類型信息創(chuàng)建正確的java對(duì)象。

  • @JsonTypeInfo – indicates details of what type information to include in serialization 指出序列化包含的類型信息細(xì)節(jié)
  • @JsonSubTypes – indicates sub-types of the annotated type 指出被注解類型的子類
  • @JsonTypeName – defines a logical type name to use for annotated class 定義被注解類使用的邏輯名稱
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public class Animal {
    public String name;
 
    public Animal(String name) {
    }
}
 
@JsonTypeName("dog")
// 這里在子類中指定的type name必須和抽象類中注解@JsonSubTypes中name屬性指定的值保持一致
public class Dog extends Animal {
    public double barkVolume;
 
    public Dog(String name) {
        super(name);
        barkVolume = 0.5;
    }
}
 
@JsonTypeName("cat")
public class Cat extends Animal {
    boolean likesCream;
    public int lives;
 
    public Cat(String name) {
        super(name);
        likesCream = true;
        lives = 10;
    }
}
  
    @Test
    public void whenSerializingPolymorphic_thenCorrect()
            throws JsonProcessingException {
        Zoo.Dog dog = new Zoo.Dog("lacy");
        Zoo zoo = new Zoo(dog);
 
        String result = new ObjectMapper()
                .writeValueAsString(zoo);
 
        assertThat(result, containsString("type"));
        assertThat(result, containsString("dog"));
    }
 
    序列化zoo對(duì)象,結(jié)果如下:
        {
         "type":"dog",
         "name":"lacy",
         "barkVolume":0
        }
 
    @Test
    public void whenDeserializingPolymorphic_thenCorrect()
            throws IOException {
        String json = "{\"name\":\"lacy\",\"type\":\"cat\"}";
 
        Animal animal =
                new ObjectMapper().readerFor(Animal.class).readValue(json);
 
        assertEquals("lacy", animal.name);
        assertEquals(Cat.class, animal.getClass());
    }

記一次jackson序列化Boolean的坑

@Data
public class CouponTemplateDto {
    /**
     * 優(yōu)惠券類型id
     */
    private Long couponTypeId;
    /**
     * 優(yōu)惠券模板id
     */
    private Long couponTemplateId;
    /**
     * 用戶id
     */
    private Long userId;

    /**
     * 優(yōu)惠券描述
     */
    private String description;
    /**
     * 面值,滿200減30,則此值為30
     */
    private BigDecimal value;
    /**
     * 從次日起,多少天可用
     */
    private Integer delayDays;
    /**
     * 從當(dāng)日起,多少天可用
     */
    private Integer nowDays;
    /**
     * 滿多少可以減,滿200減30,則此值為200
     */
    private BigDecimal fullAmount;

    /**
     * 券號(hào)
     */
    private String couponNo;

    /**
     * 有效起始日期
     */
    private Date startTime;

    /**
     * 失效日期
     */
    private Date endTime;

    /**
     * 創(chuàng)建時(shí)間
     */
    private Date createTime;

    /**
     * 使用日期
     */
    private Date useTime;

    /**
     * 券使用狀態(tài):0-未使用 1-已使用 2-已過期
     */
    private Integer couponUseStatus;
    /**
     * 過期前多少天提醒,默認(rèn)7天
     */
    private Integer overDueRemind;
    /**
     * 優(yōu)惠券標(biāo)題
     */
    private String title;

    /**
     * 優(yōu)惠券是否能開始使用
     */
//    @JsonProperty("isStart")
    private Boolean start;
    /**
     * 優(yōu)惠券是否過期
     */
//    @JsonProperty("isEnd")
    private Boolean end;

    private Boolean getStart() {
        return startTime.before(new Date());
    }

    private Boolean getEnd() {
        return endTime.before(new Date());
    }
}

我定義了一個(gè)這樣的類,我們項(xiàng)目用的是Spring Boot,默認(rèn)底層采用的是jackson序列化,但是在使用中出了一個(gè)問題private Boolean start跟private Boolean end這兩個(gè)字段一直無法序列化

總結(jié)排查思路如下

1.是boolean還是Boolean,到底是基本數(shù)據(jù)類型還是包裝類,如果是基本數(shù)據(jù)類型的話(包裝類可以使用,但是不推薦),不要使用is開頭。我們可以看看阿里巴巴規(guī)范中的這段話

【強(qiáng)制】POJO類中的任何布爾類型的變量,都不要加 is,否則部分框架解析會(huì)引起序列化錯(cuò)誤。

反例:定義為基本數(shù)據(jù)類型 boolean isSuccess;的屬性,它的方法也是 isSuccess(),RPC框架在反向解析的時(shí)候,“以為”對(duì)應(yīng)的屬性名稱是 success,導(dǎo)致屬性獲取不到,進(jìn)而拋出異常。

2.這個(gè)錯(cuò)誤也是我犯的錯(cuò)誤,我復(fù)寫了get方法,方法的訪問權(quán)限被設(shè)置成了private級(jí)別

解決方案:

  • 加注解,@JsonProperty(“isEnd”)
  • 將方法級(jí)別更正為public

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot登錄攔截器+ThreadLocal實(shí)現(xiàn)用戶信息存儲(chǔ)的實(shí)例代碼

    springboot登錄攔截器+ThreadLocal實(shí)現(xiàn)用戶信息存儲(chǔ)的實(shí)例代碼

    ThreadLocal 為變量在每個(gè)線程中創(chuàng)建了一個(gè)副本,這樣每個(gè)線程都可以訪問自己內(nèi)部的副本變量,這篇文章主要介紹了springboot登錄攔截器+ThreadLocal實(shí)現(xiàn)用戶信息存儲(chǔ)的實(shí)例代碼,需要的朋友可以參考下
    2024-03-03
  • 詳解Java并發(fā)編程之原子類

    詳解Java并發(fā)編程之原子類

    這篇文章主要為大家介紹了Java并發(fā)編程之原子類介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Java并發(fā)編程示例(三):線程中斷

    Java并發(fā)編程示例(三):線程中斷

    這篇文章主要介紹了Java并發(fā)編程示例(三):線程中斷,在本節(jié),我們所開發(fā)的示例程序?qū)?huì)創(chuàng)建一個(gè)線程,五秒鐘后,利用中斷機(jī)制強(qiáng)制中止這個(gè)線程,需要的朋友可以參考下
    2014-12-12
  • mybatis的xml中使用@符號(hào)調(diào)用類方法示例

    mybatis的xml中使用@符號(hào)調(diào)用類方法示例

    這篇文章主要為大家介紹了mybatis的xml中使用@符號(hào)調(diào)用類方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • SpringBoot項(xiàng)目打包成war包并部署在tomcat上運(yùn)行的操作步驟

    SpringBoot項(xiàng)目打包成war包并部署在tomcat上運(yùn)行的操作步驟

    我們開發(fā) SpringBoot 項(xiàng)目有時(shí)我們會(huì)需要打包成 war 包,放入外置的 Tomcat 中進(jìn)行運(yùn)行,或者使用工具idea直接啟動(dòng),便于開發(fā)調(diào)試,本文給大家分享SpringBoot項(xiàng)目打包成war包并部署在tomcat上運(yùn)行的操作步驟,感興趣的朋友一起看看吧
    2024-03-03
  • jedis連接池對(duì)commons-pool的封裝示例詳解

    jedis連接池對(duì)commons-pool的封裝示例詳解

    這篇文章主要為大家介紹了jedis連接池對(duì)commons-pool的封裝示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • MyBatis-Flex BaseMapper的接口基本用法小結(jié)

    MyBatis-Flex BaseMapper的接口基本用法小結(jié)

    本文主要介紹了MyBatis-Flex BaseMapper的接口基本用法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • 使用Java實(shí)現(xiàn)KMZ和KML數(shù)據(jù)的直接解析

    使用Java實(shí)現(xiàn)KMZ和KML數(shù)據(jù)的直接解析

    本文主要講解如何用JAVA語言,直接解析KMZ數(shù)據(jù),文章首先介紹google地圖中的KMZ和KML數(shù)據(jù),然后使用代碼的方式實(shí)現(xiàn)數(shù)據(jù)的解析,最后展示解析成果以及如何將數(shù)據(jù)轉(zhuǎn)換成空間WKT數(shù)據(jù),需要的朋友可以參考下
    2024-06-06
  • MyBatis的CRUD中的不同參數(shù)綁定查詢實(shí)現(xiàn)

    MyBatis的CRUD中的不同參數(shù)綁定查詢實(shí)現(xiàn)

    本文主要介紹了MyBatis的CRUD中的不同參數(shù)綁定查詢實(shí)現(xiàn),主要包括單個(gè)參數(shù)傳遞綁定,序號(hào)參數(shù)傳遞綁定,注解參數(shù)傳遞綁定,pojo(對(duì)象)參數(shù)傳遞綁定,map參數(shù)傳遞綁定這幾種類型,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Java中使用instanceof判斷對(duì)象類型的示例

    Java中使用instanceof判斷對(duì)象類型的示例

    在List<Object>中遍歷Object時(shí),先判斷類型,再定向轉(zhuǎn)換,本文給大家介紹Java中使用instanceof判斷對(duì)象類型,感興趣的朋友跟隨小編一起看看吧
    2023-08-08

最新評(píng)論

灵川县| 四川省| 库尔勒市| 呼图壁县| 天峻县| 吴江市| 漳平市| 镇安县| 东辽县| 兴文县| 绥棱县| 信丰县| 潍坊市| 安远县| 民县| 上思县| 大余县| 莱芜市| 苍溪县| 桃园县| 丰城市| 武平县| 宜兴市| 淄博市| 昆明市| 资溪县| 罗甸县| 武安市| 子洲县| 苗栗市| 永靖县| 民丰县| 阳泉市| 乌苏市| 东兴市| 土默特左旗| 汝州市| 桐梓县| 崇州市| 包头市| 阜阳市|