毕业设计,用SSH框架,但是想要做出异步请求数据的效果,使用了ajax方式,其中数据传递的类型为json。ajax使用用的jQuery的ajax。其实struts里也支持ajax功能,但是我觉得用太多struts的自带标签,想使用bootstrap的定义风格就不好了,页面效果会打折扣,另外个人觉得现在的更广泛的是前端的写前端的,尽量不要前台的也需要知道struts如何写,之后重构也更麻烦。[补充,搜索过一个有个插包使在struts可以用bootstrap,但是觉得可能支持的bootstrap的版本会低于当前]
言归正传,使用json的话需要使用工具,有java自带的JSONArray、JSONObject,但是使用的时候回提示存在类无法初始化,即指用到的类并不存在,需要引入其他的jar包,后来网上去查了下,导入了一些包,但是还是有问题,可能是没有完全。觉得麻烦就放弃了用这个。于是找了fastjson,自称是最快的,转换速度比gson(google)的快6倍。目前的项目你只有到github上去下载最新的,网上的很多以前的文章给出的链接已经失效。github地址:https://github.com/alibaba/fastjson 说明一句文档实在太过简略。
官方的常见问题:https://github.com/alibaba/fastjson/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
常用的方法是:
public static final String toJSONString(Object object); public static final <T> T parseObject(String text, Class<T> clazz, Feature... features);
其实参考官方的说明,更加清楚,有中文解释,这里说一下,官方没有提到的问题。1.过滤器的使用 问题: 对hibernate反向工程生成的类,若有引用其他的表的主键做外键,就会产生一个那张表的反向工程的类,这样我们对通过查询得到的记录,我是用Criteria方式查询,返回一个list对象。我们知道,hibernate查询若是采用lazy延迟方式加载(eager方式循环引用,好像容易出问题),在session关闭,再想获取未加载的数据时,会出现异常no session。不幸的是,直接使用fastjson转化对象成为json的时候就会查询未加载的对象,从而产生异常。 解决办法: 举个例子我们有一个专业培养计划表,里面又一个属性叫专业id,hibernate会生成一个专业类和专业培养计划类,培养计划类中有个成员对象是专业类对象,事实上我们并不需要专业类的其他属性,知道专业id即可,这是我们可以使用过滤器,使自己只对专业id进行序列化。这样就不会引起hibernate异常。 过滤的方式,我喜欢的方式有两种,一种是配置简单过滤器,另一种是注解方式声明不序列某属性。各有优缺点,建议结合使用。 a.配置简单过滤器
List<Professioncultivationplan> list = professioncultivationplanDao .query(professioncultivationplan); // JSON过滤 SimplePropertyPreFilter filter = new SimplePropertyPreFilter( Profession.class, "id"); //fastjosn的自带简单过滤器,允许配置只序列化那个属性,这里是序列化id,这样对于在Professioncultivationplan里的profession的其他属性就不会去序列化生成json字符串 result = JSON.toJSONString(list, filter,SerializerFeature.DisableCircularReferenceDetect);//注意SerializerFeature.DisableCircularReferenceDetect是标题的第二问题的解决方案
b. 注解
private Integer id; @JSONField(serialize = false) private Profession profession; private String groupcourseCode; private String groupcourseCategory; private Float credit; @JSONField(serialize = false) private Set<Coursecultivationplan> coursecultivationplans = new HashSet<Coursecultivationplan>( 0); //这里我对private Profession profession;private Set<Coursecultivationplan> coursecultivationplans...使用了不进行序列haunted的声明,使用注解可以不用反复使用过滤,但是明显我们也无法使用profession里的id了,若是这个id没有什么用使用注解方式是可以的,否则应该使用第一种方式,其中第一种方式只是简单的配置过滤器,还有实现一个接口,自己写一个过滤器,更加丰富是定制过滤方式,一般而言简单过滤器就可以解决了
2.转换hibernate对象出现 $ref
使用fastjson,当进行toJSONString的时候,默认如果重用对象的话,会使用引用的方式进行引用对象。也就是指,hibernate为我们的profession对象是在java里是同一个的话,序列化就会得到一个引用。还有一种叫循环引用——我们需要序列化的对象中存在循环引用,在许多的json库中,这会导致stackoverflow——的情况也会出现 $ref 。 在我的毕业设计里面并没有出现循环引用(A包含B,B有包含A),但是我获取一个专业培养计划表的时候,若是有多条结果,从第二条开始就会出现profession的序列化并不是第一个的记录的一样,而是引用第一个结果,所以传递到前端页面循环显示记录的时候,从第二条开始,专业id那一列变成了undefined,或许有其他的读取这个一列的方式,但是我想生成同样的结果,会比较方便和一致性,所以需要设置增加参数SerializerFeature.DisableCircularReferenceDetect,禁止以引用方式引用对象。一下是未设置的转换出来的json结果:
[{"corediscipline":"计算机科学与技术change","dlsjCompulsoryratio":0,"dlsjCredit":35,"dlsjElectiveratio":0,"dlsjPeriod":0,"id":1,"profession":{"id":5},"tsjyCompulsoryratio":30.9,"tsjyCredit":69.5,"tsjyElectiveratio":10.8,"tsjyPeriod":1042,"zyjcCompulsoryratio":32.4,"zyjcCredit":63,"zyjcElectiveratio":5.4,"zyjcPeriod":945,"zykCompulsoryratio":9.6,"zykCredit":36,"zykElectiveratio":10.8,"zykPeriod":510}, {"corediscipline":"计算机科学与技术save","dlsjCompulsoryratio":0,"dlsjCredit":35,"dlsjElectiveratio":0,"dlsjPeriod":0,"id":8,"profession":{"$ref":"$[0].profession"},"tsjyCompulsoryratio":30.9,"tsjyCredit":69.5,"tsjyElectiveratio":10.8,"tsjyPeriod":1042,"zyjcCompulsoryratio":32.4,"zyjcCredit":63,"zyjcElectiveratio":5.4,"zyjcPeriod":945,"zykCompulsoryratio":9.6,"zykCredit":36,"zykElectiveratio":10.8,"zykPeriod":510}]
时间: 2024-10-02 06:01:54