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

jackson json序列化實(shí)現(xiàn)首字母大寫,第二個(gè)字母需小寫

 更新時(shí)間:2021年06月29日 11:30:06   作者:二奎  
這篇文章主要介紹了jackson json序列化實(shí)現(xiàn)首字母大寫,第二個(gè)字母需小寫方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

jackson json序列化首字母大寫,第二個(gè)字母需小寫

有這樣一個(gè)類:

@Setter
@Getter
@JsonNaming(value = PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class Student {
    private String bName;
}

序列化后,希望首字母大寫,如下面的測(cè)試代碼:

@Test
    public void contextLoads() throws IOException {
        Student test = new Student();
        test.setBName("234234");
        String s = objectMapper.writeValueAsString(test);
        Assert.assertEquals("{\"BName\":\"234234\"}", s);
    }

可實(shí)際運(yùn)行后,結(jié)果與希望不一樣:

org.junit.ComparisonFailure:

Expected :{"BName":"234234"}

Actual :{"Bname":"234234"}

jackson在序列化時(shí)把第二個(gè)大寫字母n轉(zhuǎn)成了小寫,這是為什么呢?

以下是跟蹤源碼的過程:

直接找到:com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector#collectAll這個(gè)方法:

執(zhí)行完_addFields(props)方法后:

執(zhí)行完_addMethods(props)方法后:

一個(gè)是bName,一個(gè)是bname;

第一個(gè)bName取的是字段的名稱,

第二個(gè)bname是取的它的set方法:

public static String okNameForIsGetter(AnnotatedMethod am, String name,
            boolean stdNaming)
    {
        if (name.startsWith("is")) { // plus, must return a boolean
            Class<?> rt = am.getRawType();
            if (rt == Boolean.class || rt == Boolean.TYPE) {
                return stdNaming
                        ? stdManglePropertyName(name, 2)
                        : legacyManglePropertyName(name, 2);
            }
        }
        return null;
    }

根據(jù)stdNaming來(lái)決定這個(gè)name是以什么標(biāo)準(zhǔn)輸出,默認(rèn)的是false;

stdManglePropertyName 就是原始輸出。

legacyManglePropertyName 就是規(guī)范輸出。

下面的代碼就是規(guī)范輸出:

protected static String legacyManglePropertyName(final String basename, final int offset)
    {
        final int end = basename.length();
        if (end == offset) { // empty name, nope
            return null;
        }
        // next check: is the first character upper case? If not, return as is
        char c = basename.charAt(offset);
        char d = Character.toLowerCase(c);
        
        if (c == d) {
            return basename.substring(offset);
        }
        // otherwise, lower case initial chars. Common case first, just one char
        StringBuilder sb = new StringBuilder(end - offset);
        sb.append(d);
        int i = offset+1;
        for (; i < end; ++i) {
            c = basename.charAt(i);
            d = Character.toLowerCase(c);
            if (c == d) {
                sb.append(basename, i, end);
                break;
            }
            sb.append(d);
        }
        return sb.toString();
    }

主要邏輯在for循環(huán)中,去除set后,第一個(gè)字母小寫,

第二字母小寫后,與第二個(gè)字母比較,如果都是小寫,則直接接上,返回,

如果第二字母大寫,就如我們的這種情況,就以小寫的情況,接上,再去找下一個(gè)字母,直到找到小寫字母為止。

意思就是為了滿足駝峰命名規(guī)則,要規(guī)范輸出。

如果我們的字段命名正如它的規(guī)范的話,props是只有一條記錄的,因?yàn)椋好Q相同,就不插入了,由于咱們的名稱不同,所以就有兩條記錄。

protected POJOPropertyBuilder _property(Map<String, POJOPropertyBuilder> props,
            String implName)
    {
        POJOPropertyBuilder prop = props.get(implName);
        if (prop == null) {
            prop = new POJOPropertyBuilder(_config, _annotationIntrospector, _forSerialization,
                    PropertyName.construct(implName));
            props.put(implName, prop);
        }
        return prop;
    }

可是我們輸出中只有一條,沒有bName這條,

其實(shí)在是這里把第一條刪除了。因?yàn)椋?/p>

這些屬性為空,導(dǎo)致這個(gè)字段不可見:

protected void _removeUnwantedProperties(Map<String, POJOPropertyBuilder> props)
    {
        Iterator<POJOPropertyBuilder> it = props.values().iterator();
        while (it.hasNext()) {
            POJOPropertyBuilder prop = it.next();
            // First: if nothing visible, just remove altogether
            if (!prop.anyVisible()) {
                it.remove();
                continue;
            }
            // Otherwise, check ignorals
            if (prop.anyIgnorals()) {
                // first: if one or more ignorals, and no explicit markers, remove the whole thing
                if (!prop.isExplicitlyIncluded()) {
                    it.remove();
                    _collectIgnorals(prop.getName());
                    continue;
                }
                // otherwise just remove ones marked to be ignored
                prop.removeIgnored();
                if (!prop.couldDeserialize()) {
                    _collectIgnorals(prop.getName());
                }
            }
        }
    }

只剩第二記錄bname,再首字母大寫,所以就是Bname了。

解決方案:

第一個(gè)就是JsonProperty

@Setter
@Getter
@JsonNaming(value = PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class Student {
    @JsonProperty("BName")
    private String bName;
}

測(cè)試結(jié)果如下:

org.junit.ComparisonFailure:

Expected :{"BName":"234234"}

Actual :{"Bname":"234234","BName":"234234"}

雖然生成了BName,但是Bname仍在(加了JsonProperty就visable了)。

第二個(gè)就是配置

objectMapper的MapperFeature.USE_STD_BEAN_NAMIN如上文提到了,非規(guī)范化輸出。

如下代碼:

@Test
    public void contextLoads() throws IOException {
        Student test = new Student();
        test.setBName("234234");
        objectMapper.configure(MapperFeature.USE_STD_BEAN_NAMING, true);
        String s = objectMapper.writeValueAsString(test);
        Assert.assertEquals("{\"BName\":\"234234\"}", s);
    }

第三個(gè)方案:重寫PropertyNamingStrategy:

@Test
    public void contextLoads() throws IOException {
        Student test = new Student();
        test.setBName("234234");
        //objectMapper.configure(MapperFeature.USE_STD_BEAN_NAMING, true);
        objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
            private static final long serialVersionUID = 1L;
            // 反序列化時(shí)調(diào)用
            @Override
            public String nameForSetterMethod(MapperConfig<?> config,
                                              AnnotatedMethod method, String defaultName) {
                return method.getName().substring(3);
            }
            // 序列化時(shí)調(diào)用
            @Override
            public String nameForGetterMethod(MapperConfig<?> config,
                                              AnnotatedMethod method, String defaultName) {
                return method.getName().substring(3);
            }
        });
        String s = objectMapper.writeValueAsString(test);
        Assert.assertEquals("{\"BName\":\"2342344\"}", s);
    }

修改objectMapper的配置,要注意對(duì)其他功能的影響。

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

相關(guān)文章

  • java仿QQ連連看游戲

    java仿QQ連連看游戲

    這篇文章主要為大家詳細(xì)介紹了java仿QQ連連看游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Java常用 Date 時(shí)間格式化、Calender日歷、正則表達(dá)式的用法小結(jié)

    Java常用 Date 時(shí)間格式化、Calender日歷、正則表達(dá)式的用法小結(jié)

    SimpleDateFormat?是Java中用于格式化和解析日期的類,它允許你將日期對(duì)象轉(zhuǎn)換為特定格式的字符串,或者將特定格式的字符串轉(zhuǎn)換為日期對(duì)象,這篇文章主要介紹了Java常用 Date 時(shí)間格式化、Calender日歷、正則表達(dá)式的用法,需要的朋友可以參考下
    2024-12-12
  • Mybatis中ResultMap解決屬性名和數(shù)據(jù)庫(kù)字段名不一致問題

    Mybatis中ResultMap解決屬性名和數(shù)據(jù)庫(kù)字段名不一致問題

    我們Pojo類的屬性名和數(shù)據(jù)庫(kù)中的字段名不一致的現(xiàn)象時(shí)有發(fā)生,本文就詳細(xì)的介紹一下Mybatis中ResultMap解決屬性名和數(shù)據(jù)庫(kù)字段名不一致問題,感興趣的可以了解一下
    2021-10-10
  • java模擬斗地主發(fā)牌功能

    java模擬斗地主發(fā)牌功能

    這篇文章主要為大家詳細(xì)介紹了java模擬斗地主發(fā)牌,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • Java?Float?保留小數(shù)位精度的實(shí)現(xiàn)

    Java?Float?保留小數(shù)位精度的實(shí)現(xiàn)

    這篇文章主要介紹了Java?Float?保留小數(shù)位精度的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java?Bean轉(zhuǎn)Map的那些踩坑實(shí)戰(zhàn)

    Java?Bean轉(zhuǎn)Map的那些踩坑實(shí)戰(zhàn)

    項(xiàng)目中有時(shí)會(huì)遇到Map轉(zhuǎn)Bean,Bean轉(zhuǎn)Map的情況,下面這篇文章主要給大家介紹了關(guān)于Java?Bean轉(zhuǎn)Map那些踩坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • SpringBoot使用RestTemplate如何通過http請(qǐng)求將文件下載到本地

    SpringBoot使用RestTemplate如何通過http請(qǐng)求將文件下載到本地

    文章介紹了如何通過編寫代碼批量下載文件,解決了沒有提供批量下載接口的問題,首先篩選出需要下載的文件ID,然后通過后端代碼發(fā)起HTTP請(qǐng)求,將下載的資源寫入本地文件中,總結(jié)了實(shí)現(xiàn)方式和注意事項(xiàng),希望能為類似任務(wù)提供參考
    2025-02-02
  • kafka啟動(dòng)報(bào)錯(cuò)(Cluster ID)不匹配問題以及解決

    kafka啟動(dòng)報(bào)錯(cuò)(Cluster ID)不匹配問題以及解決

    這篇文章主要介紹了kafka啟動(dòng)報(bào)錯(cuò)(Cluster ID)不匹配問題以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Vue.Js及Java實(shí)現(xiàn)文件分片上傳代碼實(shí)例

    Vue.Js及Java實(shí)現(xiàn)文件分片上傳代碼實(shí)例

    這篇文章主要介紹了Vue.Js及Java實(shí)現(xiàn)文件分片上傳代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • java使用PDFRenderer實(shí)現(xiàn)預(yù)覽PDF功能

    java使用PDFRenderer實(shí)現(xiàn)預(yù)覽PDF功能

    這篇文章主要為大家詳細(xì)介紹了java使用PDFRenderer實(shí)現(xiàn)預(yù)覽PDF功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12

最新評(píng)論

花垣县| 湖南省| 呼和浩特市| 武安市| 湖口县| 共和县| 邢台市| 内黄县| 信宜市| 喀什市| 凤山市| 普定县| 清水河县| 隆化县| 和顺县| 台湾省| 信宜市| 和顺县| 泰来县| 于都县| 大理市| 扎鲁特旗| 衡阳市| 恭城| 罗平县| 金湖县| 郑州市| 新竹县| 丰县| 泰和县| 镇江市| 梓潼县| 云林县| 巧家县| 黄梅县| 贵州省| 荔浦县| 攀枝花市| 怀集县| 微山县| 中西区|