精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (11)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
作者 | 正文 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-07
最后修改:2011-01-07
在以Spring为核心的Web应用中,使用Ext作为Web前台,通过Struts2作为数据交换的“跳板”。
原本Struts2自身具备的ModelDriven接口,在使用Ext前台后变得已经没有什么大用了。
由于有struts2-json-plugin的支持,可以很方便的获取前台的数据。
有点像Ext将数据序列化后,再由后台的Java进行反序列化。但是,Ext毕竟只能提供JSON数据,它的本质还只是POST过来的字符串而已。
然而借助struts2-json-plugin提供的 Object JSONUtil.deserialize(String) 方法,可以很简单的将 request 中的字符串“反序列化”为Java对象。
但是,在实战中发现,由于“反序列化”的时候并没有一个Java类作为“模板”,所以到底“反序列化”出来的对象是什么类型的,完全由JSONUtil.deserialize方法自己决定。而它只能参考唯一的参数——那个大大的JSON字符串来决定。于是 见到形如数字的就生成 Long,有小数点的就是 Double,其他统统 String,见到[ ]就是List,见到{ }就是Map。
然而我们Java端的JavaBean中真的是这些类型吗?
那个Long可能仅仅是int,或者根本就是个String; 那个List或许是个数组; 那个Map其实是另一个JavaBean。。。
但是,JSONUtil真的猜不到呀。 多么希望JSONUtil能够提供一个这样的重载方法:deserialize(String, Class) 但是,它真的没有。
于是我在我的框架中,从Struts2的Action入手。给所有的Action类编制一个抽象父类,并在其中实现这样的“智能反序列化”功能。
写这段代码时,发现最为麻烦的就是,如果JSONUtil反序列化后得到的对象中的某个属性是集合类型,而我们的JavaBean中,它其实应该是数组或JavaBean时,如何得到集合类型泛型中的类型。
举个例子,JSON字符串经JSONUtil处理后,有个属性 stuffs 的类型是List<E>,而按照JavaBean中的定义,这个 stuffs 的类型是个数组 Human[] stuffs ,这个相对简单一些,假设从JavaBean中反射得到各个属性并遍历时,得到的属性类型为propType:
beanInfo = Introspector.getBeanInfo(type); for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) { Class propType = descriptor.getPropertyType(); }
那么 Class innerCls = propertyType.getComponentType(); 就能得到数组的元素类型,如上例中的 Human。
更为复杂的是,当JSON中的 List<E> 对应于 JavaBean 中的 List<?> 时,如果上例中,JavaBean中 stuffs 属性的类型改为 List<Human> :
那么很遗憾,我没有找到方法可以从 propTpye (List<Human>的Class)中找到并提取 Human 这个类。 只能通过 stuffs 这个属性在其JavaBean中的setter方法,取得其参数里面的泛型,来发现这个Human。 // get the inner Type ParameterizedType rType = (ParameterizedType) wm.getGenericParameterTypes()[0]; Type fType = rType.getActualTypeArguments()[0]; // Type to Class Field field = fType.getClass().getDeclaredField("name"); field.setAccessible(true); String name = (String) field.get(fType); Class innerCls = Class.forName(name);
Map中泛型也与此类型,唯一的区别是,Map中有key和value,需要取两个泛型的类型。
剩下的工作就是递归了,这样才能无线层次的构筑复杂的JavaBean对象。
详细代码如下:
AbstractAction.java
/** * Action的抽象骨架类 * */ public abstract class AbstractAction extends ActionSupport { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); // 此处省略一些与本功能无关的代码 /** * 预处理。确认request有效,并强制编码格式为UTF-8 */ private boolean proParseRequestData() { ServletRequest request = ServletActionContext.getRequest(); try { request.setCharacterEncoding("UTF-8"); } catch (UnsupportedEncodingException e) { logger.warn("Can't encoding to UTF-8. use the default encode."); } if (request == null) { logger.error("Can't get http servlet request."); return false; } else { return true; } } /** * 获取数组型JSON字符串 * 因数组型数据,前台可能有两种提交方式。一种是提交多个同名的项目,一种是提交单个以[]包裹、逗号分割的JSON格式的字符串。本方法将这两种提交方式统一化处理为JSON字符串格式 */ private String parseParametersJSONString(ServletRequest request, String propertyName) { String[] stringArray = request.getParameterValues(propertyName); if(stringArray == null){ return null; } if (stringArray.length == 1 && stringArray[0].startsWith("[")) { return stringArray[0]; } else { StringBuffer sb = new StringBuffer(); for (int i = 0; i < stringArray.length; i++) { sb.append("["); sb.append(stringArray[i]); sb.append("]"); if (i < stringArray.length - 1) { sb.append(","); } } return sb.toString(); } } /** * 解析页面提交的所有数据 从request中提取JSON序列化字符串,并据此解析出复杂的JavaBean数据(VOBean) * * @param type * 装填JavaBean的类型 * @return 装填好的JavaBean */ protected <T> T parseRequestData(Class<T> type) { // 检查并预置HttpRequest if (!proParseRequestData()) { return null; } T result = null; try { result = (T) type.newInstance(); } catch (Exception e) { logger.warn("Can't parse JOSN object."); logger.warn(e.getMessage()); } BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(type); // 获取类属性 } catch (Exception e) { logger.warn("Can't parse JOSN object."); logger.warn(e.getMessage()); } ServletRequest request = ServletActionContext.getRequest(); // 给 JavaBean 对象的属性赋值 for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) { Method wm = descriptor.getWriteMethod(); if (wm != null) { String propertyName = descriptor.getName(); Class propType = descriptor.getPropertyType(); if (propType.isArray()) { // 数组型属性 try { String jsonString = parseParametersJSONString(request, propertyName); Object jsonObj = JSONUtil.deserialize(jsonString); Object value = parseProperties(jsonObj, propType); wm.invoke(result, value); } catch (Exception e) { logger.warn("Can't set property " + propertyName); logger.warn(e.toString()); } } else if (List.class.isAssignableFrom(propType)) { Class innerCls = null; try { String propertyString = parseParametersJSONString(request, propertyName); if (propertyString != null) { // get the inner Type ParameterizedType rType = (ParameterizedType) wm.getGenericParameterTypes()[0]; Type fType = rType.getActualTypeArguments()[0]; // Type to Class Field field = fType.getClass().getDeclaredField("name"); field.setAccessible(true); String name = (String) field.get(fType); innerCls = Class.forName(name); Object jsonObj = JSONUtil.deserialize(propertyString); Object value = parseProperties(jsonObj, propType, innerCls); wm.invoke(result, value); } } catch (Exception e) { logger.warn("Can't get inner generic class."); logger.warn(e.getMessage()); } } else if (Map.class.isAssignableFrom(propType)) { try { String propertyString = parseParametersJSONString(request, propertyName); if (propertyString != null) { // get the inner Type([0] is the Key type of the Map) ParameterizedType rType1 = (ParameterizedType) wm.getGenericParameterTypes()[0]; Type fType1 = rType1.getActualTypeArguments()[0]; // Type to Class Field field1 = fType1.getClass().getDeclaredField("name"); field1.setAccessible(true); String name1 = (String) field1.get(fType1); Class innerCls1 = Class.forName(name1); // get the inner Type([1] is the Value type of the Map) ParameterizedType rType2 = (ParameterizedType) wm.getGenericParameterTypes()[1]; Type fType2 = rType2.getActualTypeArguments()[0]; // Type to Class Field field2 = fType2.getClass().getDeclaredField("name"); field2.setAccessible(true); String name2 = (String) field2.get(fType2); Class innerCls2 = Class.forName(name2); Object jsonObj = JSONUtil.deserialize(propertyString); Object value = parseProperties(jsonObj, propType, innerCls1, innerCls2); wm.invoke(result, value); } } catch (Exception e) { logger.warn("Can't get inner generic class."); logger.warn(e.getMessage()); } } else if (ClassUtil.isValueType(propType)) { Object value = null; try { String propertyString = request.getParameter(propertyName); if (propertyString != null) { value = stringToObject(propertyString, propType); wm.invoke(result, value); } } catch (Exception e) { logger.warn("Can't set property " + propertyName); logger.warn(e.getMessage()); } } else { Object value = null; try { String propertyString = request.getParameter(propertyName); if (propertyString != null) { Object jsonObj = JSONUtil.deserialize(propertyString); value = parseProperties(jsonObj, propType); wm.invoke(result, value); } } catch (Exception e) { logger.warn("Can't set property " + propertyName); logger.warn(e.getMessage()); } } } } // 返回结果 return result; } /** * 解析页面提交的某个数据 从request中提取JSON序列化字符串,并据此解析出某个复杂的JavaBean数据(VOBean) * * @param type * 装填JavaBean的类型 * @param propertyName * 预解析的属性名(在request信息中的名) * @return 装填好的JavaBean */ protected <T> T parseRequestData(Class<T> type, String propertyName) { // 检查并预置HttpRequest if (!proParseRequestData()) { return null; } ServletRequest request = ServletActionContext.getRequest(); if (type.isArray()) { try { String jsonString = parseParametersJSONString(request, propertyName); if (jsonString != null) { Object jsonObj = JSONUtil.deserialize(jsonString); return parseProperties(jsonObj, type); } } catch (Exception e) { logger.warn("Can't set property " + propertyName); logger.warn(e.getMessage()); } } else if (List.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type)) { try { String propertyString = parseParametersJSONString(request, propertyName); if (propertyString != null) { // can't get the inner Type, use Object Object jsonObj = JSONUtil.deserialize(propertyString); return parseProperties(jsonObj, type, Object.class); } } catch (Exception e) { logger.warn("Can't get inner generic class."); logger.warn(e.getMessage()); } } else if (ClassUtil.isValueType(type)) { try { String propertyString = request.getParameter(propertyName); if (propertyString != null) { return (T) stringToObject(propertyString, type); } } catch (Exception e) { logger.warn("Can't get inner generic class."); logger.warn(e.getMessage()); } } else { try { String propertyString = request.getParameter(propertyName); if (propertyString != null) { Object jsonObj = JSONUtil.deserialize(propertyString); return parseProperties(jsonObj, type); } } catch (Exception e) { logger.warn("Can't get inner generic class."); logger.warn(e.getMessage()); } } return null; } /** * 解析属性 * @param <T> 返回值类型 * @param source JSON字符串反序列得到的源数据 * @param type 返回值的类型 * @return 解析得到的Java对象 */ private <T> T parseProperties(Object source, Class<T> type) { return parseProperties(source, type, null); } /** * 解析属性 * @param <T> 返回值类型 * @param source JSON字符串反序列得到的源数据 * @param type 返回值的类型 * @param innerType 内部(泛型)类型,对应List<E>的E * @return 解析得到的Java对象 */ private <T> T parseProperties(Object source, Class<T> type, Class innerType) { return parseProperties(source, type, innerType, null); } /** * 解析属性 * @param <T> 返回值类型 * @param source JSON字符串反序列得到的源数据 * @param type 返回值的类型 * @param innerType1 内部(泛型)类型1,对应Map<K, V>的K * @param innerType2 内部(泛型)类型2,对应Map<K, V>的V * @return 解析得到的Java对象 */ private <T> T parseProperties(Object source, Class<T> type, Class innerType1, Class innerType2) { // JavaBean or Map if (source instanceof Map) { Map<Object, Object> jsonMap = (Map<Object, Object>) source; if (Map.class.isAssignableFrom(type)) { // type is Map Map<Object, Object> rtnMap = new HashMap<Object, Object>(); for (Map.Entry<Object, Object> entry : jsonMap.entrySet()) { rtnMap.put(parseProperties(entry.getKey(), innerType1), parseProperties(entry.getValue(), innerType2)); } return (T) rtnMap; } else { // JavaBean T obj = null; try { obj = type.newInstance(); } catch (Exception e) { logger.warn("Can't parse JOSN object."); logger.warn(e.getMessage()); } BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(type); // 获取类属性 } catch (Exception e) { logger.warn("Can't parse JOSN object."); logger.warn(e.getMessage()); } // 给 JavaBean 对象的属性赋值 for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) { Method wm = descriptor.getWriteMethod(); if (wm != null) { String propertyName = descriptor.getName(); Class propertyType = descriptor.getPropertyType(); try { if (jsonMap.containsKey(propertyName)) { Object value = jsonMap.get(propertyName); if (value != null) { if (propertyType.isArray()) { // get the inner Type Class innerCls = propertyType.getComponentType(); wm.invoke(obj, parseProperties(value, propertyType, innerCls)); } else if (List.class.isAssignableFrom(propertyType)) { // get the inner Type ParameterizedType rType = (ParameterizedType) wm.getGenericParameterTypes()[0]; Type fType = rType.getActualTypeArguments()[0]; // Type to Class Field field = fType.getClass().getDeclaredField("name"); field.setAccessible(true); String name = (String) field.get(fType); Class innerCls = Class.forName(name); wm.invoke(obj, parseProperties(value, propertyType, innerCls)); } else if (Map.class.isAssignableFrom(propertyType)) { // get the inner Type([0] is the Key type of the Map) ParameterizedType rType1 = (ParameterizedType) wm.getGenericParameterTypes()[0]; Type fType1 = rType1.getActualTypeArguments()[0]; // Type to Class Field field1 = fType1.getClass().getDeclaredField("name"); field1.setAccessible(true); String name1 = (String) field1.get(fType1); Class innerCls1 = Class.forName(name1); // get the inner Type([1] is the Value type of the Map) ParameterizedType rType2 = (ParameterizedType) wm.getGenericParameterTypes()[1]; Type fType2 = rType2.getActualTypeArguments()[0]; // Type to Class Field field2 = fType2.getClass().getDeclaredField("name"); field2.setAccessible(true); String name2 = (String) field2.get(fType2); Class innerCls2 = Class.forName(name2); wm.invoke(obj, parseProperties(value, propertyType, innerCls1, innerCls2)); } else if (propertyType.isAssignableFrom(value.getClass())) { wm.invoke(obj, value); } else if(ClassUtil.isValueType(propertyType)){ wm.invoke(obj, stringToObject(value.toString(), propertyType)); } else { wm.invoke(obj, parseProperties(value, propertyType)); } } } } catch (Exception e) { logger.warn("Can't set property " + propertyName); logger.warn(e.getMessage()); } } } return obj; } } else if (source instanceof List) { // List from JSON if (List.class.isAssignableFrom(type)) { // Data into a List if (ClassUtil.isValueType(type)) { return (T) source; } else { List rtn = new ArrayList(); for (Object obj : (List) source) { rtn.add(parseProperties(obj, innerType1)); } return (T) rtn; } } else { // Data into a Array List<Object> innerList = (List<Object>) source; Class arrayType = type.getComponentType(); Object[] array = (Object[]) Array.newInstance(arrayType, innerList.size()); for (int i = 0; i < innerList.size(); i++) { Object src = innerList.get(i); Object item = parseProperties(src, arrayType); array[i] = item; } return (T) array; } } else { return (T) source; } } /** * 将String转换为type所指定的类型 * * @param str * String型元数据 * @param type * 转换后的数据类型的class * @return 转换后的结果 * @throws NumberFormatException * 当参数不能转换为数值型时 */ private Object stringToObject(String str, Class type) { try { if (String.class.isAssignableFrom(type)) { return str; } if (char.class.isAssignableFrom(type)) { return str.charAt(0); } if (Character.class.isAssignableFrom(type)) { return Character.valueOf(str.charAt(0)); } if (int.class.isAssignableFrom(type)) { return Integer.valueOf(str); } if (Integer.class.isAssignableFrom(type)) { return Integer.valueOf(str); } if (boolean.class.isAssignableFrom(type)) { return Boolean.valueOf(str); } if (Boolean.class.isAssignableFrom(type)) { return Boolean.valueOf(str); } if (short.class.isAssignableFrom(type)) { return Short.valueOf(str); } if (Short.class.isAssignableFrom(type)) { return Short.valueOf(str); } if (long.class.isAssignableFrom(type)) { return Long.valueOf(str); } if (Long.class.isAssignableFrom(type)) { return Long.valueOf(str); } if (float.class.isAssignableFrom(type)) { return Float.valueOf(str); } if (Float.class.isAssignableFrom(type)) { return Float.valueOf(str); } if (double.class.isAssignableFrom(type)) { return Double.valueOf(str); } if (Double.class.isAssignableFrom(type)) { return Double.valueOf(str); } if (byte.class.isAssignableFrom(type)) { return Byte.valueOf(str); } if (Byte.class.isAssignableFrom(type)) { return Byte.valueOf(str); } if (Date.class.isAssignableFrom(type)) { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(str); } if (Calendar.class.isAssignableFrom(type)) { Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(str); Calendar result = Calendar.getInstance(); result.setTime(date); return result; } if (BigInteger.class.isAssignableFrom(type)) { return new BigInteger(str); } if (BigDecimal.class.isAssignableFrom(type)) { return new BigDecimal(str); } return null; } catch (Exception e) { return null; } } }
这里边用到了一个 ClassUtil.isValueType(Class) 方法用来判定给定的类型是为Java的值类型和基本型:
ClassUtil.java
public class ClassUtil { /** * 判定指定的 Class 对象是否表示一个值类型。 八个基本类型及它们的包装类、五个 Class 和 void。 即 * boolean、Boolean、byte、Byte、char、Character、short、Short、int、Integer、long、Long、float、Float、double、Double、String、BigInteger、BigDecimal、Date、Calendar、void。 * * @param clazz * @return 当且仅当指定类表示一个值类型时,才返回 true */ public static boolean isValueType(Class clazz) { if (clazz.isPrimitive()) { return true; } if (String.class.isAssignableFrom(clazz)) { return true; } if (Byte.class.isAssignableFrom(clazz)) { return true; } if (Character.class.isAssignableFrom(clazz)) { return true; } if (Short.class.isAssignableFrom(clazz)) { return true; } if (Integer.class.isAssignableFrom(clazz)) { return true; } if (Long.class.isAssignableFrom(clazz)) { return true; } if (Float.class.isAssignableFrom(clazz)) { return true; } if (Double.class.isAssignableFrom(clazz)) { return true; } if (Date.class.isAssignableFrom(clazz)) { return true; } if (Calendar.class.isAssignableFrom(clazz)) { return true; } if (BigInteger.class.isAssignableFrom(clazz)) { return true; } if (BigDecimal.class.isAssignableFrom(clazz)) { return true; } return false; } }
最后,在各个Action中的使用方法是:
XxxxxAction.java
// 前台提交的request就是stuffs这个对象在前台的JSON对象 Human stuffs = parseRequestData(Human.class); // 前台提交的request中的项目并非某个JavaBean的众属性,而是单独接收它们 String listType = this.parseRequestData(String.class, "listType"); boolean hasBlankItem = this.parseRequestData(Boolean.class, "hasBlankItem"); Object[] params = this.parseRequestData(Object[].class, "params");
就此我们的反序列化工具完成了,复杂的JavaBean可以成功反序列化了。
但是,期间的代码(主要是提取泛型中的类型),看上去有些丑陋,如果你知道更好的方法,请一定跟帖!
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-10
EXT非得要以JSON形式提交数据?一个对象只有某个属性改变,用得着整个提交?带宽问题不是问题?
费那么大劲反序列化,json-lib不是提供了类似的功能?真正难搞的是日期类型而已。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-10
llade 写道 EXT非得要以JSON形式提交数据?一个对象只有某个属性改变,用得着整个提交?带宽问题不是问题?
费那么大劲反序列化,json-lib不是提供了类似的功能?真正难搞的是日期类型而已。 Ext已JSON形式提交的数据,不一定非是大数据。简单的一个id和一个数量,就可以组成一个简单的JSON: {id:'0501',count:12} 这与 ?id='0501'&count=12 的数据量没有什么差异。 对于后台,可以“特意”用两个 String和int型变量去接收它们(setter注入、ModelDriven都可以,甚至getParameter), 但是,现在我想要的是一个通用的方法,把它们放入一个JavaBean中。 pulic Class MyPOJO{ private String id; private int count; // getter/setter .... } 而使用struts-json-plugin的功能,只能得到一个 Map |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-10
最后修改:2011-01-10
精神可嘉。
其实可以考虑在json中带上元数据,然后自己实现一套serialize/deserialize就简单多了。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-10
我感觉用Json-lib就挺好,能解决楼主的难处。
关于数据传输,我感觉只提交修改的数据就可以,应该数据量不大 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-10
有人能估测下EXT的发展前景吗?
我觉得这个比这篇文章重要 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-11
Ext.decode() or encode
后台拿JsonUtil |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-12
zhaoxy_sunrain 写道 我感觉用Json-lib就挺好,能解决楼主的难处。
关于数据传输,我感觉只提交修改的数据就可以,应该数据量不大 当前台是个收集数据的表格的时候,数据量就大了。 比如,修改了4行数据,添加了8行数据。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-13
TonyLian 写道 llade 写道 EXT非得要以JSON形式提交数据?一个对象只有某个属性改变,用得着整个提交?带宽问题不是问题?
费那么大劲反序列化,json-lib不是提供了类似的功能?真正难搞的是日期类型而已。 Ext已JSON形式提交的数据,不一定非是大数据。简单的一个id和一个数量,就可以组成一个简单的JSON: {id:'0501',count:12} 这与 ?id='0501'&count=12 的数据量没有什么差异。 对于后台,可以“特意”用两个 String和int型变量去接收它们(setter注入、ModelDriven都可以,甚至getParameter), 但是,现在我想要的是一个通用的方法,把它们放入一个JavaBean中。 pulic Class MyPOJO{ private String id; private int count; // getter/setter .... } 而使用struts-json-plugin的功能,只能得到一个 Map 不知道是不是误解,我说的是json-lib。 http://json-lib.sourceforge.net/usage.html 引用 From JSON to Beans
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2011-01-13
多谢LS,看来我有些重复造轮子了。 MyBean myBean = (MyBean)Xxxxx.deserialize(jsonString, MyBean.class) 3. 要求支持泛型,就是说MyBean的某个属性可能是 public class MyBean{ public Map<MyBean2, List<MyBean3>> getXxxx(){ ... } } 4. 要支持数组,不能和List弄混 public class MyBean{ public MyBean4[] getXxxxx(){ ... } }
我所搜集的信息如下:希望大家补充
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||