2008-06-19
Faceye基础版(开源)中对JSON数据的处理.
Faceye基础版下载:http://code.google.com/p/faceye/downloads/list
Faceye基础版中,对JSON数据进行了统一的处理,使得用户在操作时可以不用关注数据的细节问题,直接使用JSON格式的数据.
比如在Action中,当要输出JSON数据时,只需要:
在这里面,我们只使用了一句:
就完成了json格式数据的转化,其中,PaginationSupport 使用的Robin早期写的一个Hibernate分页对像,对于JSON数据的输出,我们只需要使用:
对于json数据的转化,我们完全在后台完成.
以下是取得分页对像的代码:
在这里,调用DAO进行简单的数据查询.
至此,返回完整的数据分页对像.
分页对像代码如下:
在分页对像的json()方法中,我们完成了从各式各样数据到json数据的转化工作.
在这里,我们主要使用了一个list2json()方法.如下:
在这里,如果我们使用的是Hiberante的实体查询,那么要求我们的实体中有
或
方法
这样
如果不是使用Hiberante的实体查询,那我们不使用这两个方法,直接使用JSONArray对对像进行转化.
以上两个方法的示例为:
至此,便是系统内对json 完整处理.而在系统的其它地方,不会存在对JSON数据的处理
******************************************************************
关于FaceYe开源portal的其它更多内容包括
:
FaceYe用户及开发人员提供文档(以下内容为FaceYe开发人员或用户提供,请尊重原著):
******************************************************************
Faceye基础版中,对JSON数据进行了统一的处理,使得用户在操作时可以不用关注数据的细节问题,直接使用JSON格式的数据.
比如在Action中,当要输出JSON数据时,只需要:
/**
* 博客点击排行榜
*/
public ActionForward blogClickOrderList(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
String timePeriod=this.get("timePeriod", request);
PaginationSupport ps=this.getBlogService().getPageOfBlogClickHistoryOrderList(timePeriod, this.getHttp().getCurrentIndex(request), this.getHttp().getCurrentPageSize(request));
String json=ps.json();
this.jsonPrint(response, json);
return null;
}
在这里面,我们只使用了一句:
ps.json();
就完成了json格式数据的转化,其中,PaginationSupport 使用的Robin早期写的一个Hibernate分页对像,对于JSON数据的输出,我们只需要使用:
this.jsonPrint(response, json);
对于json数据的转化,我们完全在后台完成.
以下是取得分页对像的代码:
public PaginationSupport getPageOfBlogClickHistoryOrderList(
String periodTime, int startIndex, int pageSize) {
// TODO Auto-generated method stub
return this.getBlogClickHistoryDao().getBlogClickOrderList(periodTime, pageSize, startIndex);
}
在这里,调用DAO进行简单的数据查询.
/**
* 点击量包括访问博客首页的量,访问单篇文章的量,其中,访问者包括FaceYe网友(既未注册用户) 同时,包括已注册用户.
*/
public PaginationSupport getBlogClickOrderList(String timePeriod,
int pageSize, int startIndex) {
if (StringUtils.isEmpty(timePeriod)) {
timePeriod = StringPool.BLOG_PERIOD_LIST_ORDER_ALL;
}
Date[] date = this.getDate(timePeriod);
String sql = "";
if (null != date) {
String start = DateUtil.parseDate(date[0], null);
String end = DateUtil.parseDate(date[1], null);
sql = "select * from (select sum(xx.blog_click_count) as 'blog_click_count',xx.portal_id as 'portal_id', xx.user_id as 'user_id', xx.username as 'username' from ("
+ "select sum(x.article_click_count) as 'blog_click_count' ,x.portal_id as 'portal_id',x.user_id as 'user_id',x.username as 'username'"
+ " from "
+ "(select p.id as 'portal_id',"
+ "uba.name as 'article_name',"
+ "count(ubac.article_id) as 'article_click_count',"
+ "ubac.article_id as 'article_id' ,u.id as 'user_id',u.name as 'username'"
+ " from "
+ "user_blog_article_click_count ubac,"
+ "user_blog_article uba,"
+ "user_blog_article_category ubc,"
+ "sys_portal_container p,"
+ "sys_user u"
+ " where "
+ "ubc.portalContainer_id=p.id "
+ "and "
+ "uba.id=ubac.article_id"
+ " and "
+ "uba.articleCategory_id=ubc.id "
+ "and "
+ "p.user_id=u.id"
+ " and ubac.createTime between '"
+ start
+ "' and '"
+ end
+ "' group by ubac.article_id "
+ " order by count(ubac.article_id) desc) x "
+ " group by x.portal_id "
+
"union "
+
"select count(ubch.id) as 'blog_click_count',p.id as 'portal_id',u.id as 'user_id',u.name as 'username' from "
+ "user_blog_click_history ubch,"
+ "sys_portal_container p,"
+ "sys_user u"
+ " where ubch.portalContainer_id =p.id and p.user_id=u.id "
+ " and ubch.createTime between '"
+ start
+ "' and '"
+ end + "' group by portal_id " +
") xx group by xx.portal_id order by blog_click_count desc) xxx";
} else {
sql = "select * from (select sum(xx.blog_click_count) as 'blog_click_count',xx.portal_id as 'portal_id', xx.user_id as 'user_id', xx.username as 'username' from ("
+ "select sum(x.article_click_count) as 'blog_click_count' ,x.portal_id as 'portal_id',x.user_id as 'user_id',x.username as 'username'"
+ " from "
+ "(select p.id as 'portal_id',"
+ "uba.name as 'article_name',"
+ "count(ubac.article_id) as 'article_click_count',"
+ "ubac.article_id as 'article_id' ,u.id as 'user_id',u.name as 'username'"
+ " from "
+ "user_blog_article_click_count ubac,"
+ "user_blog_article uba,"
+ "user_blog_article_category ubc,"
+ "sys_portal_container p,"
+ "sys_user u"
+ " where "
+ "ubc.portalContainer_id=p.id "
+ "and "
+ "uba.id=ubac.article_id"
+ " and "
+ "uba.articleCategory_id=ubc.id "
+ "and "
+ "p.user_id=u.id"
+ " group by ubac.article_id "
+ " order by count(ubac.article_id) desc) x "
+ " group by x.portal_id "
+
"union "
+
"select count(ubch.id) as 'blog_click_count',p.id as 'portal_id',u.id as 'user_id',u.name as 'username' from "
+ "user_blog_click_history ubch,"
+ "sys_portal_container p,"
+ "sys_user u"
+ " where ubch.portalContainer_id =p.id and p.user_id=u.id group by portal_id"
+
") xx group by xx.portal_id order by blog_click_count desc) xxx";
}
return this.getBaseJdbcDao().getPage(sql, pageSize, startIndex);
}
至此,返回完整的数据分页对像.
分页对像代码如下:
package com.faceye.core.util.helper;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
public class PaginationSupport {
public final static int PAGESIZE = 15;
private int pageSize = PAGESIZE;
private List items;
private int totalCount;
private int[] indexes = new int[0];
private int startIndex = 0;
public PaginationSupport(List items) {
setItems(items);
setPageSize(items.size());
setTotalCount(items.size());
setStartIndex(0);
}
public PaginationSupport(List items, int totalCount) {
setPageSize(PAGESIZE);
setTotalCount(totalCount);
setItems(items);
setStartIndex(0);
}
public PaginationSupport(List items, int totalCount, int startIndex) {
setPageSize(PAGESIZE);
setTotalCount(totalCount);
setItems(items);
setStartIndex(startIndex);
}
public PaginationSupport(List items, int totalCount, int pageSize,
int startIndex) {
setPageSize(pageSize);
setTotalCount(totalCount);
setItems(items);
setStartIndex(startIndex);
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
if (totalCount > 0) {
this.totalCount = totalCount;
int count = totalCount / pageSize;
if (totalCount % pageSize > 0) {
count++;
}
indexes = new int[count];
for (int i = 0; i < count; i++) {
indexes[i] = pageSize * i;
}
} else {
this.totalCount = 0;
}
}
public int[] getIndexes() {
return indexes;
}
public void setIndexes(int[] indexes) {
this.indexes = indexes;
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
if (totalCount <= 0) {
this.startIndex = 0;
} else if (startIndex >= totalCount) {
this.startIndex = indexes[indexes.length - 1];
} else if (startIndex < 0) {
this.startIndex = 0;
} else {
this.startIndex = indexes[startIndex / pageSize];
}
}
public int getNextIndex() {
int nextIndex = getStartIndex() + pageSize;
if (nextIndex >= totalCount) {
return getStartIndex();
} else {
return nextIndex;
}
}
public int getPreviousIndex() {
int previousIndex = getStartIndex() - pageSize;
if (previousIndex < 0) {
return 0;
} else {
return previousIndex;
}
}
public List transItems() {
return CollectionUtil.getCollectionUtil().transList(this.getItems());
}
/**
* 将分页像中的数据转化为标准的JSON分页结构
*
* @return
*/
public String json() {
if (CollectionUtils.isNotEmpty(this.getItems())) {
return JSONUtil.pageJson(this.getTotalCount(), CollectionUtil
.getCollectionUtil().list2Json(this.transItems()));
} else {
return null;
}
}
}
在分页对像的json()方法中,我们完成了从各式各样数据到json数据的转化工作.
在这里,我们主要使用了一个list2json()方法.如下:
/**
* 将一个结果集转化为json数据结构
*
* @param source
* @return
*/
public String list2Json(List source) {
try {
if (null == source || source.isEmpty()) {
return null;
}
StringBuffer json = null;
if (source.get(0) instanceof Map) {
json = new StringBuffer(JSONArray.fromObject(source).toString());
} else {
json = new StringBuffer(StringPool.CHARACTER_MIDDLE_LEFT);
for (int i = 0; i < source.size(); i++) {
Object item = source.get(i);
if (item instanceof BaseObject) {
Class clazz = item.getClass();
if (ClassUtils.hasMethod(clazz,
StringPool.REFLECTION_METHOD_JSON, null)) {
String temp=ReflectionUtils.invokeMethod(
ClassUtils.getMethodIfAvailable(clazz,
StringPool.REFLECTION_METHOD_JSON,
null), item).toString();
json.append(temp);
} else {
json.append(JSONArray.fromObject(item).toString());
}
} else if (item instanceof Map) {
json.append(JSONArray.fromObject(item).toString());
}
json.append(StringPool.CHARACTER_COMMA);
}
json.deleteCharAt(json.lastIndexOf(StringPool.CHARACTER_COMMA));
json.append(StringPool.CHARACTER_MIDDLE_RIGHT);
}
return json.toString();
} catch (Exception e) {
return null;
}
}
在这里,如果我们使用的是Hiberante的实体查询,那么要求我们的实体中有
public Stirng json(){...}
或
public Map map(){...}
方法
这样
如果不是使用Hiberante的实体查询,那我们不使用这两个方法,直接使用JSONArray对对像进行转化.
以上两个方法的示例为:
public Map map(){
Map map=new HashMap();
map.put("id", this.getId());
map.put("name", this.getName());
map.put("content", this.getContent());
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
map.put("createTime", dateFormat.format(this.getCreateTime()));
map.put("categoryId", this.getArticleCategory().getId());
map.put("categoryName", this.getArticleCategory().getName());
map.put("discusCount", this.getDiscusCount());
map.put("clickCount", this.getClickCount());
return map;
}
public String json(){
StringBuffer sb=new StringBuffer("{");
sb.append("\"id\":");
sb.append("\"");
sb.append(this.getId());
sb.append("\"");
sb.append(",");
sb.append("\"name\":");
sb.append("\"");
sb.append(this.getName());
sb.append("\"");
sb.append(",");
sb.append("\"content\":");
sb.append("\"");
sb.append(this.getContent());
sb.append("\"");
sb.append(",");
sb.append("\"createTime\":");
sb.append("\"");
sb.append(this.getCreateTime());
sb.append("\"");
sb.append(",");
sb.append("\"categoryId\":");
sb.append("\"");
sb.append(this.getArticleCategory().getId());
sb.append("\"");
sb.append(",");
sb.append("\"categoryName\":");
sb.append("\"");
sb.append(this.getArticleCategory().getName());
sb.append("\"");
sb.append("}");
return sb.toString();
}
至此,便是系统内对json 完整处理.而在系统的其它地方,不会存在对JSON数据的处理
******************************************************************
关于FaceYe开源portal的其它更多内容包括
:
- FaceYe开源portal(Ext Tree,Portal,Struts,Spring,Hibernate,MySQL,SSH)介绍总站(含FaceYe小组联系方式)http://ecsun.javaeye.com
- FaceYe开源portal(Ext Tree,Portal,Struts,Spring,Hibernate,MySQL,SSH)运行预览图http://ecsun.javaeye.com/album
- FaceYe开源portal(Ext Tree,Portal,Struts,Spring,Hibernate,MySQL,SSH)最新下载[url]http://faceye.googlecode.com[url]
- FaceYe开源portal(Ext Tree,Portal,Struts,Spring,Hibernate,MySQL,SSH)基础版(开源)介绍(总述)http://ecsun.javaeye.com/blog/205750
- FaceYe开源portal(Ext Tree,Portal,Struts,Spring,Hibernate,MySQL,SSH)(基础版)中对JavaScript的动态加载 http://ecsun.javaeye.com/blog/210441
- FaceYe开源portal(Ext Tree,Portal,Struts,Spring,Hibernate,MySQL,SSH)(基础版)中对带复选框的树结构的处理 http://ecsun.javaeye.com/blog/205911
- FaceYe开源portal(Ext Tree,Portal,Struts,Spring,Hibernate,MySQL,SSH)(基础版)中对JSON数据的处理.http://ecsun.javaeye.com/blog/205882
- FaceYe开源portal(Ext Tree,Portal,Struts,Spring,Hibernate,MySQL,SSH)(基础版)安全框架总述(acegi功能加强版)http://ecsun.javaeye.com/blog/212877
FaceYe用户及开发人员提供文档(以下内容为FaceYe开发人员或用户提供,请尊重原著):
- FaceYe部署及相关问题解决http://code.google.com/p/faceye/wiki/deployFaceyeProject
******************************************************************


评论
2 大数据量的json序列化如果优化。10M级别。
我想如果是这么大级别的json对象,应该考虑从业务逻辑这块来优化一下需求叻,10M级别的json传输过来,估计页面上的大小远远大于10M叻,IE对Html文件的处理的限制是10M叻,所以可以考虑和客户谈谈需求,看看有没有更好的use case可以来解决用户的要求的。
对于Hibernate的级联数据,由于考虑到性能,级联的数据并不会马上加载,所以我们在每个实体中加了一个
public String json(){...}或是
public Map map(){...}方法
在这两个方法中,对数据进行统一的转化.对于级联数据,提前加载到map或String中,这样解决了在使用JSONArray中出现在级联数据加载出现异常的情况.
对于我们里面提供的JDBC查询,我们向外提供了统一的数据结构,json的转化,非常 方便.
我们并不会这样去处理json
在Faceye基础版(开源)中,对json的处理,具体到每一个实体,每一个分页对像的操作中,不会出现这种大批量的json处理,也就是说,我们将任务进行了分散.有10M级别的JSON,不明白在什么地方有
如果你真有这么大的json结构需要处理,建议可以考虑定时任务.
2 大数据量的json序列化如果优化。10M级别。