浏览 2178 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-19
最后修改:2009-12-20
小弟是菜鸟,拍砖就免了,希望大家提一些好的建议,并帮忙测试我好优化 发一个正常零配置的 struts 代码 @ParentPackage("json-default") @Result(type="json", name = "success") public class ProvinceJsonAction extends PersistAction <Province>{ private static final long serialVersionUID = -3508124153476681702L; private List <Province> provinces; @Autowired private ProvinceService provinceService; public String getProvincesJson() { provinces = provinceService.findAll(); return SUCCESS; } @JSON public List <Province> getProvinces() { return provinces; } public void setProvinces(List <Province> provinces) { this.provinces = provinces; } } 正常情况下, struts的jsonplugin能帮我们把provinces ,或者其他的对象转为json, 并发送到前台,他已经帮我们实现了很好了 但是,有时候,需求,还是不能满足, 1. 当你封装的对象,比如Province ,里面的还有city,school, teacher,等,对象 当你只需要Province,city ,school ,不需要teacher的时候,你需要在school 里面getTeacher() 方法上面 配置@JSON(serialize=false) ,但是请注意,你用了hibernate,teacher是一个底层实体 , 当你取其他对象的时候,级联了school,也需要teacher,并且,这个teacher 是必须的时候?? 你是无法取出的,因为你已经配置了, 2 .Hibernate的查询(q.)一般默认为三层,但是,jsonplugin 是把你的所有对象都给找出来, 这个时侯很容易造成数据冗余,我就是为了要Province , 但是他吧city ,school,也给我了,我不需要啊,你或许说,恩可以配置,@JSON(serialize=false) ,请看问题1 3 ,jsonplugin 对Hibernate one-to -many,one-to-one 的处理,存在一点小问题, 当他们配置为lazy的时候,jsonplugin处理的方式是,抛出异常 下面是我对他的修改,希望大家,多多提意见 为json.java 添加一个属性 package com.googlecode.jsonplugin.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface JSON { String name() default ""; String exclude() default ""; boolean serialize() default true; boolean deserialize() default true; String format() default ""; } 新增加exclude() //这个意思你不需要在Hibernate实体bean里面配置@json(serialize=false) // 在当前action配置就可以 @JSON(exclude="city,school") public List <Province> getProvinces() { return provinces; } 他忽略 Province下的city,school, 修改jsonWriter.java ,源代码就不全发了,太长,有兴趣的,可以自己去下 private Integer acount = 1 ; private String excludeBean = "" ; /** * Instrospect bean and serialize its properties */ private void bean(Object object) throws JSONException { /** *当大于四层的时候,忽略 */ if(this.acount>4) { log.warn(" bean name["+object.getClass().getName()+"]beyond 4 level ,has ignore "); this.add(null) ; return ; } this.add("{"); BeanInfo info; try { Class clazz = object.getClass(); info = ((object == this.root) && this.ignoreHierarchy) ? Introspector .getBeanInfo(clazz, clazz.getSuperclass()) : Introspector .getBeanInfo(clazz); PropertyDescriptor[] props = info.getPropertyDescriptors(); boolean hasData = false; for (int i = 0; i < props.length; ++i) { PropertyDescriptor prop = props[i]; String name = prop.getName(); Method accessor = prop.getReadMethod(); Method baseAccessor = null; /* * jsonplugin已经解决了一部分问题...clazz.getName().indexOf("$$EnhancerByCGLIB$$") > -1 *但是还不够 */ if (clazz.getName().indexOf("$$EnhancerByCGLIB$$") > -1) { try { baseAccessor = Class.forName( clazz.getName().substring(0, clazz.getName().indexOf("$$"))) .getMethod(accessor.getName(), accessor.getParameterTypes()); } catch (Exception ex) { log.debug(ex.getMessage(), ex); } } else baseAccessor = accessor; if (baseAccessor != null) { JSON json = baseAccessor.getAnnotation(JSON.class); if (json != null) { if (!json.serialize()) continue; if (json.name().length() > 0) name = json.name(); /* * 取出曾经添加的忽略的属性 */ else if(json.exclude().length()>0) { this.excludeBean += json.exclude()+"," } } //忽略 if(excludeBean.length()>0) { if(name.indexOf(excludeBean)>-1) { log.debug("excludeBean["+name+"] ignore") ; continue; } } //ignore "class" and others if (this.shouldExcludeProperty(clazz, prop)) { continue; } String expr = null; if (this.buildExpr) { expr = this.expandExpr(name); if (this.shouldExcludeProperty(expr)) { continue; } expr = this.setExprStack(expr); } Object value = accessor.invoke(object, new Object[0]); //计数 this.acount+=1; //当one-to-one的时候,value的值的格式,(去不出来) ,设置为空 if(value!=null) { if(value.getClass().getName().indexOf("$$EnhancerByCGLIB$$") > -1){ log.debug("hibernate one to one ,name["+name+"] set value=null"); value = null; } } boolean propertyPrinted = this.add(name, value, accessor, hasData); hasData = hasData || propertyPrinted; if (this.buildExpr) { this.setExprStack(expr); } } } // special-case handling for an Enumeration - include the name() as a property */ if (object instanceof Enum) { Object value = ((Enum) object).name(); this.add("_name", value, object.getClass().getMethod("name"), hasData); } } catch (Exception e) { throw new JSONException(e); } this.add("}"); } /** * Add name/value pair to buffer */ private boolean add(String name, Object value, Method method, boolean hasData) throws JSONException { if (!excludeNullProperties || value != null) { if (hasData) { this.add(','); } this.add('"'); this.add(name); this.add("\":"); //当value 是one-to-mang的hashset的集合时,设为null if(value instanceof PersistentSet){ log.debug("hibernate one-to -many,name["+name+"] set value =null") ; this.value(null, method) ; }else{ this.value(value, method) ; } //计数 this.acount-=1; return true; } return false; } ----------------end------------------------------------ 这样子,就可以解决json与Hibernate之间的大部分问题 1.数据只取三层 2.对one-ton-many ,one-to-one ,值设为null(被设置为延迟加载的时候) 3.不需要配置底层实体,在当前action配置就可以 恩,希望大家帮帮测试,谢谢了 我的邮箱hanjk1234@163.com, 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-12-21
兄弟们,能提一些意见吗......大哥们...莫非,JE 没人?,号称专业滴.........
|
|
返回顶楼 | |