天天看點

JSON 中JsonConfig的使用問題

作者:程式你好

在前後端資料傳輸互動中,經常會遇到字元串(String)與json,XML等格式互相轉換與解析,其中json以跨語言,跨前後端的優點在開發中被頻繁使用,基本上可以說是标準的資料交換格式。以前用fastjson比較多,最近項目使用net.sf.json包進行json格式轉換,也碰到一些問題在這裡記錄一下。

功能方面比較強大支援各種類型之間的轉換,比如:

JSONObject,JSONArray,JavaBean與json字元串互轉,List與json字元串互轉,Map與json字元串互轉,JSONArray與List互轉,JSONArray與數組互轉、XML與JSON互轉等。

java對象轉換成json時提供很多的方法進行控制,可以友善自定義資料類型和格式轉換處理。

JSON 中JsonConfig的使用問題

可是Json轉換Java bean對象的時候,幾乎沒有提供什麼友善的方式。

比如:我們的代碼裡,裝置實時采集參數裡有boolean類型資料,json中是true,false類型,java bean對象中需要轉換成 float的1,0。像這樣很簡單的一個需求,結果在jsonconfig中沒有找到合适的方法,上網搜尋這方面的資料也很少,幾乎說的都是java轉json方面的内容。

經過檢視net.sf.json源代碼,發現其中實作了一系列的Morpher類進行類型轉換處理,可以以資料類型為入口,按資料類型添加處理邏輯進而進行資料類型轉換的控制。

比如我的java對象中的屬性是float類型,我自己可以實作一個自定義的float類型的Morpher進行float類型轉換。建立一個float類型轉換類BooleanToFloatMorpher ,繼承自AbstractDecimalMorpher。

package com.cnooc.common.utils;


import net.sf.ezmorph.MorphException;
import net.sf.ezmorph.object.NumberMorpher;
import net.sf.ezmorph.primitive.AbstractDecimalMorpher;
;
import net.sf.ezmorph.primitive.FloatMorpher;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;




public class BooleanToFloatMorpher extends  AbstractDecimalMorpher {
    private float defaultValue = 0f;


    public BooleanToFloatMorpher() {
    }


    public BooleanToFloatMorpher(float defaultValue) {
        super(true);
        this.defaultValue = defaultValue;
    }


    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (obj == null) {
            return false;
        } else if (!(obj instanceof BooleanToFloatMorpher)) {
            return false;
        } else {
            BooleanToFloatMorpher other = (BooleanToFloatMorpher)obj;
            EqualsBuilder builder = new EqualsBuilder();
            if (this.isUseDefault() && other.isUseDefault()) {
                builder.append(this.getDefaultValue(), other.getDefaultValue());
                return builder.isEquals();
            } else {
                return !this.isUseDefault() && !other.isUseDefault() ? builder.isEquals() : false;
            }
        }
    }


    public float getDefaultValue() {
        return this.defaultValue;
    }


    public int hashCode() {
        HashCodeBuilder builder = new HashCodeBuilder();
        if (this.isUseDefault()) {
            builder.append(this.getDefaultValue());
        }


        return builder.toHashCode();
    }


    public float morph(Object value) {
        float result;
        if(value == null){
            return  this.getDefaultValue();
        }
        if(value.toString().toLowerCase().equals("true")){
            return 1f;
        }
        if(value.toString().toLowerCase().equals("false")){
            return 0f;
        }


        if (this.isUseDefault()) {
            result = new Float((new FloatMorpher(this.defaultValue)).morph(value));
        } else {
            result = new Float((new FloatMorpher()).morph(value));
        }


        return result;
    }


    public Class morphsTo()
    {
        Class var10000;
            try {
                var10000 = Class.forName("java.lang.Float");
            } catch (ClassNotFoundException var4) {
                throw new NoClassDefFoundError(var4.getMessage());
            }
        return var10000;
    }
}

           

方法:morphsTo()

這個屬于處理的入口,資料類型是java.lang.Float時候,使用這個類進行資料轉換。

方法:public float morph(Object value)

該方法是具體的轉換邏輯,輸入值是true,false時,轉換成1,0。

最後,在調用轉換方法之前,把自定義的轉換器注冊到JSONUtils裡。

JSONUtils.getMorpherRegistry().registerMorpher(new BooleanToFloatMorpher(),true);           

轉換:

config.setRootClass(MongoWits58.class);
           
JSONObject.toBean(data, config);           

總結:

這種轉換方式簡單粗暴,不像java轉json那樣可以按屬性名稱和類型控制轉換字段,隻能按目标類的資料類型進行轉換處理,其實在源代碼中提供了源類的資料類型控制參數,不知道為啥轉換處理的時候沒有使用此參數。理想情況是能提供按參數字段名稱,源類的字段資料類型,字段名稱,目标類資料類型,字段名稱進行轉換控制。