Coundy

             漫步風中,傾聽自己的腳步,在自我沉浸中,找尋逝去的靈魂

          posts - 27,comments - 2,trackbacks - 0
          問題:Struts2框架的rest-plugin插件中jsonlib庫,在序列化時因對象循環引用時觸發異常。為了在解決這個問題,修改該插件的源代碼并重發編譯。
          思路:解決這個問題,用了一個簡單的思路,就是將jsonlib序列化前,先將循環引用解除,在代碼中使用遞歸和堆棧。
          缺失:由于該方式采用如果存在循環引用就返回null值的方式,因此這種方式不具反序列化可行性,需要進一步改進思路。
          參考:目前開源的fastjson已經解決了對象循環引用問題
          // 處理數組的循環引用
          private Object disCycleArray(Object obj, Object owner)
          throws IllegalArgumentException, IllegalAccessException {
          if (null != obj) {
          if (!isRefObject(getComponetType(obj)))
          return obj;
          Object[] objects = (obj instanceof Collection) ? ((Collection) obj)
          .toArray() : ((Object[]) obj);
          for (int i = 0; i < objects.length; i++) {
          objects[i] = disCycleObject(objects[i], owner);
          }
          if (obj instanceof Collection) {
          Set collection = new HashSet();
          CollectionUtils.addAll(collection, objects);
          return collection;
          }
          return objects;
          }
          return null;
          }
          private Object disCycleObject(Object obj, Object owner)
          throws IllegalArgumentException, IllegalAccessException {
          if (null == obj)
          return null;
          else if (null == owner || obj == owner) {
          roots.put(obj.hashCode(), obj);
          } else {
          if (!contains(roots, owner)) {
          roots.put(owner.hashCode(), owner);
          }
          if (contains(roots, obj))
          return null;
          }
          if (null != obj) {
          Field[] fields = obj.getClass().getDeclaredFields();
          for (Field f : fields) {
          f.setAccessible(true);
          Object value = f.get(obj);
          if (null != value && !"".equals(value))
          if (isArray(value)) {
          Object newvalue = disCycleArray(value, obj);
          f.set(obj, newvalue);
          } else {
          if (isRefObject(f.getType())) {
          if (contains(roots, value)) {
          f.set(obj, null);
          } else {
          Object newvalue = disCycleObject(value, obj);
          f.set(obj, newvalue);
          }
          }
          }
          }
          //roots.remove(obj.getClass().getName());
          roots.remove(obj.hashCode());
          return obj;
          }
          return null;
          }
          private Class getComponetType(Object obj) {
          if (null != obj) {
          if (isArray(obj)) {
          Object[] objects = (obj instanceof Collection) ? ((Collection) obj)
          .toArray() : ((Object[]) obj);
          return objects.length > 0 ? (objects[0] == null ? null
          : objects[0].getClass()) : null;
          }
          }
          return null;
          }
          private boolean isRefObject(Class<?> clz) {
          if (null != clz)
          if (!clz.isPrimitive()
          && !clz.getName().startsWith("java.util")
          && !clz.getName().matches(
          "java.lang.(?!\\bObject\\b$)\\S+$")
          && !clz.getName().startsWith("java.io")) {
          return true;
          }
          return false;
          }
          private boolean contains(Map<Integer, Object> roots, Object obj) {
          if (null != obj) {
          Object target = roots.get(obj.hashCode());
          if (null != target) {
          return true;
          }
          }
          return false;
          }
          private boolean isArray(Object obj) {
          return obj instanceof Collection || obj.getClass().isArray();
          }
          posted on 2013-03-27 11:46 Coundy 閱讀(514) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 丹阳市| 北川| 临沭县| 浪卡子县| SHOW| 沙坪坝区| 庆安县| 崇信县| 时尚| 嘉兴市| 南平市| 嵊泗县| 新营市| 甘洛县| 江陵县| 桃源县| 怀远县| 公主岭市| 石林| 建水县| 泰兴市| 永和县| 六枝特区| 崇仁县| 沙雅县| 扶沟县| 彩票| 和平县| 台湾省| 周口市| 岑巩县| 肥乡县| 邵阳市| 潼关县| 山阴县| 凤城市| 鄢陵县| 浏阳市| 东方市| 灵宝市| 衡山县|