java手动拼接Ext组件json数据的简单方法
2011-01-06 16:28
417 查看
Ext的很多组件如grid, comboBox, tree等都有自己json数据格式, 一般我们需要在后台把数据库的数据进行拼接返回给前端。 以前我一直使用的是json-lib这个库,进行java object的json格式化的; 也有过一段时间是自己手动拼接json的。 这个2个办法在用过多次之后都有些不方便的地方:
使用json-lib:
这个库可以把对象,数组相应的转换成json格式。例如grid来说,我一般直接把实体对象转换成数组,以后还要拼接一下grid需要的一些数据。或者自己手动写个类型就是是grid对象的json格式,生成对象后直接转换也可以。
可是有时候,没必要传送那么多数据回去,一行表的字段也许仅仅需要几个而已。
遇到外键字段,json-lib就是不知道怎么转化了。所以这样就要自定义一个类去封装。
手动拼接:
有时候我还喜欢这么搞,简单明了的。但对于数据比较多,或是大量使用情况。就会纠缠在无数的StringBuilder的append中间。大量的"'"符号,不同字段的get方法,“,”的处理让人很抓狂,也很重复很无聊。
下面我总结了一个比较简单的手动拼接的方法,以ext grid为例子。
这是一个grid的接受数据的标准格式, 可以看到有些东西是固有的,比如都是{}, result, rows, [], {}这样的。后台拼接的时候,真正动态的就是rows里面的每一行,列名和列数据,如 id 和 1这样的。其它的都是固定的格式。我的这个方法的核心就是,变与不变的分离。不变的是固定的格式,什么时候[], 什么时候{} 等等; 变化就是存放在实体对象中的属性名和属性值。
一步步来,首先,我们需要一个接口,它的职责就是实现一个方法可以返回变化的数据。变化的数据我们可以看出来,是k-v的形式,属性值和属性名。属性名永远是string类型,值则是任意的。看接口定义如下:
这个接口我是定义在action基础类里的,所以是static的当然可以不这么做。这个接口只有一个方法,他有一个参数就是需要提取变化数据的对象,就是实体对象,这里是泛型的因为实体对象类型运行时确定。 返回值是一个Object数组,我没有用map类型数据格式来存放k-v。而是约定,这个数组每2项为一个整体存放k和v。为什么是Object因为刚才说了,实体对像的属性值是任何的可能类型,所以统一看成老祖宗类型。
接下来,需要一个方法来提取实体对象中的可变数据,如下:
因为Grid中的可变数据就是rows里的东西,所以可变json数据只是grid json整体的一部分,这个方法里的sb就是整体的json, 传入到这个方法表明需要完成整理中,rows里可变数据的部分。 entityList就是rows里的数据行, 每一行的数据如何拼接呢? 这就以来刚才定义的那个接口。property所引用的是一个实现了接口方法的对象。 方法调用中,我们看到我给接口方法传进去了Object, 而方法为我们返回 k-v形式的可变数据,我们进行json格式的拼装。
再往后呢,我们来看看grid 整体json是如何构建的:
这个方法构建了grid的整体json, 方法中体用了getObjectJson去构建可变数据部分。 property依然是作为参数传递进来的。 由此可见这个接口是让使用者自己实现的。 因为一个对象那些属性需要拼接成json是需要具体对待的。
最后我们看看如何使用这些:
这是一个重载了getGridJson的方法,参数是一个page对象, 分页对象是从数据库查询出来的。 page对象可以获得数据的总行数,和实体对象列表,这正是原getGridJson说需要的。 那么剩下一个IProperty接口,我们就地new了一个匿名类,实现了唯一的一个方法。由于是泛型的类型,我们在实现方法中拿到了具体的类型,这样我们就地new了一个Objcet数组直接初始化了。 数据就如同前面约定的,一个值是属性名,一个值是属性值。
在action中得到page对象后,直接调用这个方法就可以得到grid json了。实体对象需要的属性,由具体重载的getGridJson去定制,这样如果是外键对象也可以根据需要get出具体的属性k-v。
使用json-lib:
这个库可以把对象,数组相应的转换成json格式。例如grid来说,我一般直接把实体对象转换成数组,以后还要拼接一下grid需要的一些数据。或者自己手动写个类型就是是grid对象的json格式,生成对象后直接转换也可以。
可是有时候,没必要传送那么多数据回去,一行表的字段也许仅仅需要几个而已。
遇到外键字段,json-lib就是不知道怎么转化了。所以这样就要自定义一个类去封装。
手动拼接:
有时候我还喜欢这么搞,简单明了的。但对于数据比较多,或是大量使用情况。就会纠缠在无数的StringBuilder的append中间。大量的"'"符号,不同字段的get方法,“,”的处理让人很抓狂,也很重复很无聊。
下面我总结了一个比较简单的手动拼接的方法,以ext grid为例子。
{ results: 2000, // Reader's configured totalProperty rows: [ // Reader's configured root // record data objects: { id: 1, firstname: 'Bill', occupation: 'Gardener' }, { id: 2, firstname: 'Ben' , occupation: 'Horticulturalist' }, ... ] }
这是一个grid的接受数据的标准格式, 可以看到有些东西是固有的,比如都是{}, result, rows, [], {}这样的。后台拼接的时候,真正动态的就是rows里面的每一行,列名和列数据,如 id 和 1这样的。其它的都是固定的格式。我的这个方法的核心就是,变与不变的分离。不变的是固定的格式,什么时候[], 什么时候{} 等等; 变化就是存放在实体对象中的属性名和属性值。
一步步来,首先,我们需要一个接口,它的职责就是实现一个方法可以返回变化的数据。变化的数据我们可以看出来,是k-v的形式,属性值和属性名。属性名永远是string类型,值则是任意的。看接口定义如下:
/** * 提供获得对象属性名值数据的接口 * * @author scottCgi * @since 2010-12-26 * @param <T> */ public static interface IProperty<T> { /** * 获得对象属性值和名的数组 * * @param object 需要提取数据的对象 * @return 对象属性值和名的数组 */ Object[] getProperty(T object); }
这个接口我是定义在action基础类里的,所以是static的当然可以不这么做。这个接口只有一个方法,他有一个参数就是需要提取变化数据的对象,就是实体对象,这里是泛型的因为实体对象类型运行时确定。 返回值是一个Object数组,我没有用map类型数据格式来存放k-v。而是约定,这个数组每2项为一个整体存放k和v。为什么是Object因为刚才说了,实体对像的属性值是任何的可能类型,所以统一看成老祖宗类型。
接下来,需要一个方法来提取实体对象中的可变数据,如下:
/** * 拼接对象json字符辅助对象 * * @param sb 存放json的StringBuilder对象 * @param entityList 实体对象列表 * @param property 需要返回的实体对象属性名和值 */ private void getObjectJson(StringBuilder sb, List<T> entityList, IProperty<T> property) { Object[] objects = null; for(T entity : entityList) { objects = property.getProperty(entity); sb.append("{"); for(int i = 0; i < objects.length; i += 2) { sb.append("'").append(objects[i]).append("':'").append(objects[i + 1]).append("',"); } sb.replace(sb.lastIndexOf(","), sb.length(), "").append("},"); } if(entityList.size() != 0) { sb.replace(sb.lastIndexOf(","), sb.length(), ""); } }
因为Grid中的可变数据就是rows里的东西,所以可变json数据只是grid json整体的一部分,这个方法里的sb就是整体的json, 传入到这个方法表明需要完成整理中,rows里可变数据的部分。 entityList就是rows里的数据行, 每一行的数据如何拼接呢? 这就以来刚才定义的那个接口。property所引用的是一个实现了接口方法的对象。 方法调用中,我们看到我给接口方法传进去了Object, 而方法为我们返回 k-v形式的可变数据,我们进行json格式的拼装。
再往后呢,我们来看看grid 整体json是如何构建的:
/** * 获得实体对象列表的grid json字符串 * * @param <T> * @param entityList 实体对象列表 * @param totalCount 实体对象总数据数 * @param property 需要返回的实体对象属性名和值 * @return 实体对象列表的grid json字符串 */ public String getGridJson(List<T> entityList, long totalCount, IProperty<T> property) { StringBuilder sb = new StringBuilder(); sb.append("{") .append("totalCount:") .append(totalCount) .append(",") .append("rows: ["); this.getObjectJson(sb, entityList, property); sb.append("]}"); return sb.toString(); }
这个方法构建了grid的整体json, 方法中体用了getObjectJson去构建可变数据部分。 property依然是作为参数传递进来的。 由此可见这个接口是让使用者自己实现的。 因为一个对象那些属性需要拼接成json是需要具体对待的。
最后我们看看如何使用这些:
@Override public String getGridJson(Page<Cinema> page) { return this.getGridJson(page.getResult(), page.getTotalCount(), new IProperty<Cinema>(){ @Override public Object[] getProperty(Cinema o) { return new Object[]{ "id", o.getId(), "name", o.getName(), "introduce", o.getIntroduce(), "information", o.getInformation() }; } }); }
这是一个重载了getGridJson的方法,参数是一个page对象, 分页对象是从数据库查询出来的。 page对象可以获得数据的总行数,和实体对象列表,这正是原getGridJson说需要的。 那么剩下一个IProperty接口,我们就地new了一个匿名类,实现了唯一的一个方法。由于是泛型的类型,我们在实现方法中拿到了具体的类型,这样我们就地new了一个Objcet数组直接初始化了。 数据就如同前面约定的,一个值是属性名,一个值是属性值。
在action中得到page对象后,直接调用这个方法就可以得到grid json了。实体对象需要的属性,由具体重载的getGridJson去定制,这样如果是外键对象也可以根据需要get出具体的属性k-v。
相关文章推荐
- java后台返回前端数据的方式json,html 组装json的技术struts2-json-plugin,fast-json,Gson,手动拼接
- Ext中JsonStore重新设置url然后加载数据的方法
- Java构造和解析Json数据的两种方法详解2
- Java构造和解析Json数据的两种方法详解二
- Java构造和解析Json数据的两种方法详解2
- Java构造和解析Json数据的两种方法详解
- Java构造和解析Json数据的两种方法详解
- Java创建和解析Json数据方法(三)——json-lib包的使用
- Java构造和解析Json数据的两种方法详解二
- Ext.data.JsonStore使用HttpProxy加载数据时传递参数的两种方法
- Java构造和解析Json数据的两种方法详解一
- EasyUi-tree-json格式数据的构造(Java拼接)
- java接口数据json过滤字段方法整理
- Java构造和解析Json数据的两种方法详解(01)
- php里少用到的session_module_name,以及session的key值限制,简单将session存储为json格式数据的方法
- Java构造和解析Json数据的两种方法详解2
- Java构造和解析Json数据的两种方法详解2
- Java构造和解析Json数据的两种方法详解一
- Java构造和解析Json数据的两种方法详解二