在使用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:
1public static <T> T jsonToModel(String str, Class<? extends Model<?>> clazz) { 2 // 使用fastjson先反序列化成json对象 3 JSONObject json = JSON.parseObject(str); 4 // 获取table 5 Table table = TableMapping.me().getTable(clazz); 6 // 得到属性类型的map 7 Map<String, Class<?>> typeMap = table.getColumnTypeMap(); 8 Model<?> model = null; 9 try { 10 model = clazz.newInstance(); 11 } catch (Exception e) { 12 throw new RuntimeException(e); 13 } 14 Set<Entry<String, Class<?>>> enterSet = typeMap.entrySet(); 15 for (Entry<String, Class<?>> entry : enterSet) { 16 String attr = entry.getKey(); 17 Class<?> type = entry.getValue(); 18 if (Short.class.equals(type)) { 19 // 短整型 20 model.set(attr, json.getShort(attr)); 21 } else if (Integer.class.equals(type)) { 22 // 整型 23 model.set(attr, json.getInteger(attr)); 24 } else if (Long.class.equals(type)) { 25 // 长整型 26 model.set(attr, json.getLong(attr)); 27 } else if (Float.class.equals(type)) { 28 // 浮点型 29 model.set(attr, json.getFloat(attr)); 30 } else if (Double.class.equals(type)) { 31 // 双精度浮点型 32 model.set(attr, json.getDouble(attr)); 33 } else if (BigDecimal.class.equals(type)) { 34 // big decimal 35 model.set(attr, json.getBigDecimal(attr)); 36 } else if (String.class.equals(type)) { 37 // 字符串 38 model.set(attr, json.getString(attr)); 39 } else if (java.sql.Date.class.equals(type)) { 40 // 年月日的日期类型 41 Date date = json.getDate(attr); 42 model.set(attr, 43 date == null ? null : new java.sql.Date(date.getTime())); 44 } else if (Time.class.equals(type)) { 45 // 年月日的日期类型 46 Date date = json.getDate(attr); 47 model.set(attr, date == null ? null : new Time(date.getTime())); 48 49 } else if (Timestamp.class.equals(type)) { 50 // 时间戮 51 Date date = json.getDate(attr); 52 model.set(attr, 53 date == null ? null : new Timestamp(date.getTime())); 54 } else if (Boolean.class.equals(type)) { 55 // 布尔型 56 model.set(attr, json.getBoolean(attr)); 57 } 58 // 其它的忽略,可能还有字节数组类型 59 // 具体model的属性可能有哪些类型可以参考 TableBuilder.doBuild()代码 60 61 } 62 63 return (T) model; 64 }
本人水平有限,可能代码有不妥不优雅之处,希望各位不要拍砖,多提点建议。