JSON 中JsonConfig的使用问题

2022-11-18 15:37:08 浏览数 (1)

在前后端数据传输交互中,经常会遇到字符串(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转换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。

代码语言:javascript复制
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里。

代码语言:javascript复制
JSONUtils.getMorpherRegistry().registerMorpher(new BooleanToFloatMorpher(),true);

转换:

代码语言:javascript复制
config.setRootClass(MongoWits58.class);
代码语言:javascript复制
JSONObject.toBean(data, config);

总结:

这种转换方式简单粗暴,不像java转json那样可以按属性名称和类型控制转换字段,只能按目标类的数据类型进行转换处理,其实在源代码中提供了源类的数据类型控制参数,不知道为啥转换处理的时候没有使用此参数。理想情况是能提供按参数字段名称,源类的字段数据类型,字段名称,目标类数据类型,字段名称进行转换控制。

0 人点赞