在前后端数据传输交互中,经常会遇到字符串(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那样可以按属性名称和类型控制转换字段,只能按目标类的数据类型进行转换处理,其实在源代码中提供了源类的数据类型控制参数,不知道为啥转换处理的时候没有使用此参数。理想情况是能提供按参数字段名称,源类的字段数据类型,字段名称,目标类数据类型,字段名称进行转换控制。