在使用JFinal进行开发时,我们可能会需要解决这样的问题:Model进行json的序列化与反序列化。
官方已经提供了序列化的方法Model.toJson()非常方便,反序列化就得自己实现一下了。
之前我一直都是把Model序列化成的json字符串,反序列化成map,然后再调用Model.setAttrs(map)。这样就有类型转换问题,最后反序列化得到的Model,原本的日期类型成了字符串,Long可能会成为Integer类型,再调用getLong()和getDate()就会报错。所以,必须要在反序列化进行属性类型的精确转换。通过TableMapping.me().getTable(modelClass) 可以得到model对应的Table;table有个columnTypeMap成员变量,是列名和类型的映射;利用这个特性就可以实现精确转换了。
下面是具体代码实现,使用了fastjson:
public static <T> T jsonToModel(String str, Class<? extends Model<?>> clazz) {
// 使用fastjson先反序列化成json对象
JSONObject json = JSON.parseObject(str);
// 获取table
Table table = TableMapping.me().getTable(clazz);
// 得到属性类型的map
Map<String, Class<?>> typeMap = table.getColumnTypeMap();
Model<?> model = null;
try {
model = clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
Set<Entry<String, Class<?>>> enterSet = typeMap.entrySet();
for (Entry<String, Class<?>> entry : enterSet) {
String attr = entry.getKey();
Class<?> type = entry.getValue();
if (Short.class.equals(type)) {
// 短整型
model.set(attr, json.getShort(attr));
} else if (Integer.class.equals(type)) {
// 整型
model.set(attr, json.getInteger(attr));
} else if (Long.class.equals(type)) {
// 长整型
model.set(attr, json.getLong(attr));
} else if (Float.class.equals(type)) {
// 浮点型
model.set(attr, json.getFloat(attr));
} else if (Double.class.equals(type)) {
// 双精度浮点型
model.set(attr, json.getDouble(attr));
} else if (BigDecimal.class.equals(type)) {
// big decimal
model.set(attr, json.getBigDecimal(attr));
} else if (String.class.equals(type)) {
// 字符串
model.set(attr, json.getString(attr));
} else if (java.sql.Date.class.equals(type)) {
// 年月日的日期类型
Date date = json.getDate(attr);
model.set(attr,
date == null ? null : new java.sql.Date(date.getTime()));
} else if (Time.class.equals(type)) {
// 年月日的日期类型
Date date = json.getDate(attr);
model.set(attr, date == null ? null : new Time(date.getTime()));
} else if (Timestamp.class.equals(type)) {
// 时间戮
Date date = json.getDate(attr);
model.set(attr,
date == null ? null : new Timestamp(date.getTime()));
} else if (Boolean.class.equals(type)) {
// 布尔型
model.set(attr, json.getBoolean(attr));
}
// 其它的忽略,可能还有字节数组类型
// 具体model的属性可能有哪些类型可以参考 TableBuilder.doBuild()代码
}
return (T) model;
}
本人水平有限,可能代码有不妥不优雅之处,希望各位不要拍砖,多提点建议。