woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

使用JSON实现代码分离

在学习JSON之前,当我在写大量JSP页面的时候,产生动态数据一般采用两种途径:
1.
直接在页面中写java代码

2
采用各种标签代替

这两种用法的支持者都很多,但是我发现就算是采用标签也好,对于页面的重用还是无能为力,比如有几个页面都需要用到一个item数据,一个是管理用户页面,一个是订单页面。我们既要在管理用户的servlet写上setAttribute('item',item),也要在管理订单的servlet写上setAttribute('item',item);然后在页面上通过getAttribute()获得数据:

Java代码 clip_image001

  1. <%for(int i=0;i<item.length;++i){%>   
  2.      html tag ...   
  3. <%}%>  


或者采用标签的形式:

 

Java代码 clip_image001

  1. <ww:iterator value="item">   
  2.      html tag...   
  3. <ww:iterator>  


很多时候我们会采用 <jsp:inclue page="common.jsp"/>来重用这样的页面,但这里有个问题,如果多个的页面样式不一样呢?如果数据不是很多呢,这样会产生很多页面碎片,实践已经证明,重用页面并不是一个好办法.

有时候我想,如果我能单独用一个action来提供输出数据,每个需要这些数据的页面页面都去获取这些数据,关于这些数据在页面如何渲染是页面的问题,这个action只提供数据,这样我们重用数据不是比重用页面好很多么?

但是之前的技术并不能支撑这样的实现,一个页面如何自己主动去访问它需要的数据呢?

答案是当然是通过AJAX技术.但今天我介绍的是另外一种技术JSON.

先简单的介绍一下JSON(虽然很多人已经知道),JSON JavaScirp Object Notion 可以看成一段javascript对象树,比如 user.id 表示的是user对象的id,如果对webwork或则是srtus2.0熟悉的朋友应该对此并不陌生,对象树可以嵌套对象,比如user.cat.age 表示user对象的成员cat的年龄。除了对象还可以嵌套数组方法user.cat[0].sayHello();
我们这样声明一个JSON:

 

Java代码 clip_image001

  1. var user = { id:’1, name:’sanyun’};       
  2. alert(user.id)  //输出1   
  3. user = { id:’1, cat:{age:2,color:’white’ }};   
  4. alert(user.cat.age) //输出2  


但是JSON本身是不能和后端通信的,不过我们可以通过

 

Java代码 clip_image001

  1. <script type="text/javascript" src="后端资源"> </script>  


来和服务器后端通信.
我们可以把它封装成一个方法:

Java代码 clip_image001

  1. function CallBack(model) {   
  2.     this.model = model;   
  3. }   
  4. CallBack.init = function (url) {   
  5.      var headElement = document.getElementsByTagName("head").item(0);   
  6.      var scriptTag = document.createElement("script");   
  7.      scriptTag.setAttribute("type", "text/javascript");   
  8.      scriptTag.setAttribute("src", url);   
  9.      headElement.appendChild(scriptTag);   
  10. };  


不过需要注意的是采用这种方式后台MIME必须要设置为 html/Javascritp,当然你也可以轻松把这种方式替换成Ajax.
解析
通信之后我们需要做的是解析数据,一般来说,我们可以通过for in 简单的遍列JSON

 

Java代码 clip_image001

  1.    //model表示后端产生的JSON   
  2. CallBack.update(model){   
  3.   for(i in model){   
  4.       var node =document.getElementByID(i);   
  5.      if(node){   
  6.         node.value = model[i];   
  7.       }   
  8.    }   
  9. }  


后台

 

Java代码 clip_image001

  1. public class ShowType extends HttpServlet {   
  2.        
  3.    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {   
  4.        
  5.     response.addHeader("Cache-Control", "no-cache");  //(1)   
  6.     response.setContentType("HTML/JavaScript;charset=GBK");//(2)   
  7.     PrintWriter out = response.getWriter();   
  8.     String json = ” {name:'jiangyunpeng', status:'1',sex:'female'}   ”//(3)   
  9.     out.print("CallBack.update("+json+")"); //(4)   
  10.    }        
  11. }  


(1)首先需要设置缓存为空
(2)
然后MIME必须要设置为 html/Javascritp
(3)
产生一段JSON,这里我们是手动产生的,可以采用JSON开源框架
(4)
调用我们前面页面定义的JS函数


通过这样处理了之后我们的页面再也没有任何JAVA代码或者自定义标签了,他完全是一个HTML页面(当然这里为了演示,把解析JSON过程过于简单化了),他具有这些好处:
1.
它是一个HTML,响应速度比JSP
2.
对于一些表单元素,比如checkbox,select,如果采用java代码会很繁琐
,

Java代码 clip_image001

  1. function initCheckbox(){   
  2.    if('<%=status%>'==1){  //这里有JAVA代码   
  3.        document.getElementById('checkbox').checked = true;   
  4.     }else{   
  5.        document.getElementById('checkbox').checked = fasle;   
  6.      }   
  7. }  


但是如果采用JSON的话

 

Java代码 clip_image001

  1. function initCheckbox(){   
  2.    if(status==1){      //这里只有JSON   
  3.        document.getElementById('checkbox').checked = true;   
  4.     }else{   
  5.        document.getElementById('checkbox').checked = fasle;   
  6.      }   
  7. }  


我们可以把这段代码放在解析方法里面,判断查询的对象如果是checkbox,就像上面这样处理,这样我们就可以更本不用关心它是否是checkbox
3.
重用了数据.多个页面可以通过JSON访问相同的数据,这里没有setAttribute(),也不用考虑生命周期。
4.
降低了服务器端的负载。因为我们把解析的数据任务放在客户端里面进行,服务器只需要产生一些JSON字符串。
5.
分离了JAVA代码和JS,诸如验证,判断,很多时候在javascript里面嵌套java,可读性很差。

小结:我觉得采用JSON是个不错的选择,大家可以试试。clip_image002原来大伙早知道啦!
参考:http://www.javaworld.com/javaworld/jw-11-2006/jw-1115-json.html

 

我也是在用JSON,但不是像这样的动态生成js脚本,而是为了处理大批表格数据的读取问题,用struts(1.2)action来生成json字符串,再用response.getWriter().write()输出到页面,ExtJS自然就是用Ext.data.JsonStore来读取了。这种方式的效率比较高,也达到了代码分离的目的,逻辑层和数据访问层根本无需暴露在web上,页面虽然是jsp,也无需使用<%%>或者struts标签。欢迎交流~

我先贴部分代码上来和大家交流一下,目前处于开发初期阶段,稍后我才做一个sample放上来。

Java代码 clip_image001

  1. /**
  2. * 向浏览器输出JSON字符串
  3. * @param response HttpServletResponse对象
  4. * @param obj 任意对象,可以是List,也可以是单个对象
  5. */  
  6. public void writeJsonString(HttpServletResponse response, Object obj) throws IOException {   
  7.     if( obj == null ) {   
  8.         this.exception = "obj参数为空";   
  9.          logger.error(this.exception);   
  10.         throw new NullPointerException(this.exception);   
  11.      }   
  12.        
  13.      JSONArray array = JSONArray.fromObject(obj);   
  14.        
  15.     try {   
  16.          String json = array.toString();   
  17.         if( json.startsWith("[") ) {   
  18.              json = json.substring(1);   
  19.          }   
  20.         if( json.endsWith("]") ) {   
  21.              json = json.substring(0, json.length()-1);   
  22.          }   
  23.          response.setCharacterEncoding("utf-8");   
  24.          response.getWriter().write(json);   
  25.      } catch (IOException e) {   
  26.         this.exception = "向浏览器输出JSON字符串时发生错误";   
  27.          logger.error(this.exception);   
  28.          logger.error(e);   
  29.         throw new IOException(this.exception);   
  30.      }   
  31. }  



这里是js部分

Java代码 clip_image001

  1. var store = new Ext.data.JsonStore({   
  2.      url: '../demo.do', //请大家根据实际情况修改action路径   
  3.      root: 'data', //传回来的JSON字符串是HashMap生成的,data对应具体的数据集,一般是List对象   
  4.      totalProperty: 'totalCount', //总记录数,整型   
  5.      id: 'id',   
  6.      fields: ['title', 'state', {name:'createDate', type: 'date'}, 'author', {name:'id', type:'int'}]   
  7. });   
  8. store.setDefaultSort('id', 'asc');   
  9. store.load({params:{start:0, limit:25}}); //传两个URL参数做分页处理  


还需要说明的是:需要json-lib-2.1-jdk15.jar, ezmorph-1.0.3.jar,到附件中取。

 

posted on 2009-07-28 10:51 肥仔 阅读(1162) 评论(0)  编辑 收藏 引用 所属分类: Web-前台


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理