中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

jackson json序列化實現首字母大寫,第二個字母小寫的方法

發布時間:2021-06-29 14:36:56 來源:億速云 閱讀:844 作者:chen 欄目:開發技術

本篇內容介紹了“jackson json序列化實現首字母大寫,第二個字母小寫的方法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

有這樣一個類:

@Setter
@Getter
@JsonNaming(value = PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class Student {

    private String bName;

}

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

@Test
    public void contextLoads() throws IOException {

        Student test = new Student();
        test.setBName("234234");

        String s = objectMapper.writeValueAsString(test);

        Assert.assertEquals("{\"BName\":\"234234\"}", s);

    }

可實際運行后,結果與希望不一樣:

org.junit.ComparisonFailure:

Expected :{"BName":"234234"}

Actual   :{"Bname":"234234"}

jackson在序列化時把第二個大寫字母n轉成了小寫,這是為什么呢?

以下是跟蹤源碼的過程:

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

jackson json序列化實現首字母大寫,第二個字母小寫的方法

執行完_addFields(props)方法后:

jackson json序列化實現首字母大寫,第二個字母小寫的方法

執行完_addMethods(props)方法后:

jackson json序列化實現首字母大寫,第二個字母小寫的方法

一個是bName,一個是bname;

第一個bName取的是字段的名稱,

第二個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;
    }

根據stdNaming來決定這個name是以什么標準輸出,默認的是false;

stdManglePropertyName 就是原始輸出。

legacyManglePropertyName 就是規范輸出。

下面的代碼就是規范輸出:

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循環中,去除set后,第一個字母小寫,

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

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

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

如果我們的字段命名正如它的規范的話,props是只有一條記錄的,因為:名稱相同,就不插入了,由于咱們的名稱不同,所以就有兩條記錄。

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這條,

jackson json序列化實現首字母大寫,第二個字母小寫的方法

其實在是這里把第一條刪除了。因為:

jackson json序列化實現首字母大寫,第二個字母小寫的方法

這些屬性為空,導致這個字段不可見:

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了。

解決方案:

第一個就是JsonProperty

@Setter
@Getter
@JsonNaming(value = PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class Student {

    @JsonProperty("BName")
    private String bName;

}

測試結果如下:

org.junit.ComparisonFailure:

Expected :{"BName":"234234"}

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

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

第二個就是配置objectMapper的MapperFeature.USE_STD_BEAN_NAMIN如上文提到了,非規范化輸出。

如下代碼:

@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);

    }

第三個方案:重寫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;
            // 反序列化時調用
            @Override
            public String nameForSetterMethod(MapperConfig<?> config,
                                              AnnotatedMethod method, String defaultName) {
                return method.getName().substring(3);
            }
            // 序列化時調用
            @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的配置,要注意對其他功能的影響。

“jackson json序列化實現首字母大寫,第二個字母小寫的方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

固原市| 东源县| 南皮县| 海丰县| 乐昌市| 五常市| 连州市| 古交市| 花垣县| 略阳县| 东辽县| 岳池县| 和硕县| 林口县| 慈利县| 紫金县| 全州县| 钟山县| 砚山县| 临洮县| 岑溪市| 济源市| 南昌县| 吴江市| 大庆市| 盐池县| 安化县| 延庆县| 大渡口区| 雅安市| 新蔡县| 营口市| 库尔勒市| 北票市| 丽江市| 正镶白旗| 蓬溪县| 义马市| 华亭县| 大化| 阳曲县|