一种简单的json解析方法

       在前面的新闻系统设计中,常常会用到有关ajax的请求,如对文章类别的动态调用.本来struts2提供了一个json的插件,不过在开发的时候还不知道.自己写了一个,还将就吧.
      基本原理,就是改变struts2的返回类型,原来的返回类型为string,如果返回类型为void即不返回任何类型,而改由struts2的的ServletContext对象获得用到输出的out对象,将json对象输出到页面上,同样可以达到ajax格式效果.最后在页面上作了小小的操作,将json格式的字符串变成js对象进行调用,以完成相应操作.流程如下:

  1. 获得response对象,进行获得printWriter对象
  2. 将想要返回给页面上的对象转化成json格式的字符串
  3. 由printWriter将json字符串写到页面输出流(通常是被js来获得结果)
  4. 页面处理json字符串,转化成js对象,传入回调函数进行调用

这里主要用到几个对象ServletContext(这个是struts2的工具对象,可获得request,response等对象),JsonUtil(自己写的一个类,用到转化对象),protype.js(用到提交ajax请求,接收返回结果),此外,还有一个jsonUtil的辅助类BeanUtil(用到将javaBean转化成map对象).这里主要贴出jsonUtil的转换方法和BeanUtil的辅助方法,看这种方式是否合适.

java 代码
  1. public class JsonUtil {   
  2.     public JsonUtil() {}   
  3.   
  4.   
  5.     private static boolean isSimpleType(Class clazz) {   
  6.         return clazz.isPrimitive() || String.class.isAssignableFrom(clazz) || Number.class.isAssignableFrom(clazz)   
  7.                 || java.util.Date.class.isAssignableFrom(clazz) || Boolean.class.isAssignableFrom(clazz)   
  8.                 || Character.class.isAssignableFrom(clazz);   
  9.     }   
  10.   
  11.   
  12.     public static String convertToJson(Object obj) {   
  13.         JsonHandle jsonHandle = new JsonHandle();   
  14.   
  15.         return jsonHandle.convertToJson(0, obj).toString();   
  16.     }   
  17.   
  18.     private static class JsonHandle {   
  19.         public static final int DEFAULT_DEPTH = 10;   
  20.   
  21.   
  22.         public StringBuffer convertToJson(int depth, Object obj) {   
  23.             StringBuffer sb = new StringBuffer();   
  24.   
  25.             if(obj == null) {   
  26.                 sb.append("null");   
  27.             } else if(isSimpleType(obj.getClass())) {   
  28.                 if((obj instanceof String) || (obj instanceof java.util.Date)) {   
  29.                     sb.append("\"").append(obj).append("\"");   
  30.                 } else if(obj instanceof Character) {   
  31.                     sb.append("'").append(obj).append("'");   
  32.                 } else {   
  33.                     sb.append(obj);   
  34.                 }   
  35.             } else if(obj instanceof Collection) {   
  36.                 boolean hibernateFlag;   
  37.                 try {   
  38.                     ((Collection) obj).size();   
  39.                     hibernateFlag = true;   
  40.                 } catch(Exception ex) {   
  41.                     hibernateFlag = false;   
  42.                 }   
  43.   
  44.                 if(hibernateFlag) {   
  45.                     sb.append("[");   
  46.   
  47.                     for(Iterator iterator = ((Collection) obj).iterator(); iterator.hasNext();) {   
  48.                         sb.append(convertToJson(depth, iterator.next()));   
  49.   
  50.                         if(iterator.hasNext()) {   
  51.                             sb.append(",");   
  52.                         }   
  53.                     }   
  54.   
  55.                     sb.append("]");   
  56.                 } else {   
  57.                     sb.append("null");   
  58.                 }   
  59.   
  60.             } else if(obj.getClass().isArray()) {   
  61.                 sb.append("[");   
  62.   
  63.                 int max = java.lang.reflect.Array.getLength(obj);   
  64.   
  65.                 for(int i = 0; i < max; i++) {   
  66.                     if(i > 0) {   
  67.                         sb.append(",");   
  68.                     }   
  69.   
  70.                     sb.append(convertToJson(depth, java.lang.reflect.Array.get(obj, i)));   
  71.                 }   
  72.   
  73.                 sb.append("]");   
  74.             } else if(java.util.Map.class.isAssignableFrom(obj.getClass())) {   
  75.                 sb.append("{\n");   
  76.   
  77.                 for(Map.Entry e : ((Map) obj).entrySet()) {   
  78.                     if(!(e.getKey() instanceof String))//如果键值不是字符串,则跳过.   
  79.                         continue;   
  80.                     sb.append(e.getKey()).append(":");   
  81.   
  82.                     if(depth <= DEFAULT_DEPTH) {   
  83.                         sb.append(convertToJson(depth + 1, e.getValue()));   
  84.                     } else {   
  85.                         sb.append("undefined");   
  86.                     }   
  87.   
  88.                     sb.append(",");   
  89.                 }   
  90.   
  91.                 if(sb.length() > 3) {   
  92.                     sb.deleteCharAt(sb.length() - 1);   
  93.                 }   
  94.   
  95.                 sb.append("\n}");   
  96.             } else {   
  97.                 Map map = null;   
  98.   
  99.                 try {   
  100.                     map = BeanUtil.getPropertiesByReflect(obj);   
  101.                 } catch(Exception ex) {   
  102.                     ex.printStackTrace();   
  103.                 }   
  104.   
  105.                 sb.append(convertToJson(depth, map));   
  106.             }   
  107.   
  108.             return sb;   
  109.         }   
  110.     }   
  111. }  

以及辅助类:

java 代码
  1. public class BeanUtil {   
  2.   
  3.     /** Creates a new instance of BeanUtil */  
  4.     private BeanUtil() {   
  5.     }   
  6.   
  7.     public static Map getPropertiesByReflect(Object obj) throws Exception {   
  8.         if(obj == null)   
  9.             return null;   
  10.         Field[] fields = obj.getClass().getDeclaredFields();   
  11.         if(fields == null || fields.length == 0)   
  12.             return null;   
  13.         Map map = new HashMap();   
  14.         AccessibleObject.setAccessible(fields, true);   
  15.         for(Field field : fields) {   
  16.             if(!field.getName().equals("serialVersionUID") && field.getAnnotation(Fly_m.class) == null)   
  17.                 map.put(field.getName(), field.get(obj));   
  18.   
  19.         }   
  20.         if(map.size() < 1)   
  21.             return null;   
  22.         return map;   
  23.     }   
  24.   
  25. }  


        在JsonUtil里,主要对一个对象进行分析,采取不同的策略对不同类型的对象进行递归性地转化.对应集合类型,采用迭代地方式.而进行通用的javaBean对象,则先将其转化成一个map对象,然后再进行转化.在本程序中,用到了一个转化深度地概念,主要是防止某些类地无限属性或者递归属性.考虑到并不需要将对象中的每一个属性进行转化,这里引入了一个相当于Traisient的注释@Fly_m,作用到字段上(因为对javaBean的解析是以反射来解析的).如果解析的属性存在这个注解,则被忽略.(一开始想要transient的modifier属性,发现与hibernate相冲突(hiberante对于transient的属性也不会解析?).

#-----------------------------
在客户端,我采用protype.js提供的基本的ajax调用方法Ajax.Request(action,{method,parameters,onComplete,onException)这种访求进行服务器请求,同时写了一个小小的辅助js进行调用,以方便页面调用.Fly_m.js,使用这个js后,通常的调用被简单化为m_ylf.invoke(actionName,method,parameters,callBack).这样,只需要四个参数,同时内置调试参数设置,以及传递给callBack对象的不再是一个xmlHttpRequest对象,而是一个已经eval好的js对象,让使用更加方便.源码如下:

js 代码
  1. var m_ylf = function() {};   
  2. m_ylf.defaultPath = "js";   
  3. m_ylf.preDebug = false;   
  4. m_ylf.postDebug = false;   
  5. m_ylf.prefix="";   
  6.   
  7. m_ylf.setPrefix = function(pre) {   
  8.     m_ylf.prefix = pre;   
  9. }   
  10.   
  11. m_ylf.setPreDebug = function(pre){   
  12.     m_ylf.preDebug = pre;   
  13. }   
  14.   
  15. m_ylf.setPostDebug = function(post) {   
  16.     m_ylf.postDebug = post;   
  17. }   
  18.   
  19. m_ylf.handleException = function(exception) {   
  20.     window.alert("Error -> " + exception.message);   
  21. }   
  22.   
  23. m_ylf.invoke = function(actionName, param, callBack) {   
  24.        
  25.     if(arguments.length != 3)   
  26.         return;   
  27.     if(typeof callBack != "function") {   
  28.         callBack = function() {};   
  29.     }       
  30.        
  31.     if(actionName == null || actionName == "")   
  32.         return;   
  33.   
  34.     var params = null;   
  35.     if(param == null || param == "")   
  36.         params = "";   
  37.     else    
  38.         params = param;   
  39.        
  40.     if(m_ylf.preDebug)   
  41.         alert(params);   
  42.        
  43.        
  44.     var action = actionName + ".p";   
  45.     if(m_ylf.prefix != null && m_ylf.prefix != "")   
  46.         action = m_ylf.prefix + action;   
  47.        
  48.     new Ajax.Request(action,   
  49.         {method:"get",   
  50.          parameters:params,            
  51.          onComplete:function(data) {   
  52.             if(m_ylf.postDebug) {   
  53.                 window.alert(data.responseText);   
  54.             }   
  55.                           
  56.             var temp = "(" + data.responseText + ")";   
  57.             temp = eval(temp);   
  58.   
  59.             callBack(temp);   
  60.          },   
  61.          onException:m_ylf.handleException   
  62.          });   
  63. }  

不过有个小小的缺点,就是这个js只是符合我自己的系统设计,如果想要通用些,就需要改变其中第44行的action定义,不过我想这通常没有再大的问题吧.preDebug属性可查看请求参数,而postDebug可查看返回给客户端的json字符串,以进行相关的结果跟踪.

我想这个小小的json转化类帮助一些小的开发还行,大的开发就不行了,因为可以涉及到对象的解析,以及生成json字符串的速度.不过对于要求不太高的应用还是足够了.而且页面上的请求都是最基本的请求,完全可以在基础之上进行添加新的功能.以后有想法再在上面作些文章.
相关源码放在附件中,需要的同学们可下来看看.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值