Jackson注解使用

今天在使用Jackson将对象转化成JSON对象时报错,于是将jeecms中转化对象为JSON的方式看了一下,代码如下:

@RequiresPermissions("menu:v_ajax_edit")
@RequestMapping("/menu/v_ajax_edit.do")
public void ajaxEdit(Integer id, HttpServletRequest request,HttpServletResponse response, ModelMap model) throws         JSONException {
    JSONObject object = new JSONObject();
    CmsUserMenu menu=manager.findById(id);
    if(menu!=null){
        object.put("id", menu.getId());
        object.put("name", menu.getName());
        object.put("priority", menu.getPriority());
        object.put("url", menu.getUrl());
    }
    ResponseUtils.renderJson(response, object.toString());
}
`

`
可以看到jeecms是先声明了一个JSON对象,然后将需要生成的参数逐个put到JSON对象中,最后通过toString方法生成一个JSON字符串,并通过 HttpServletResponse 返回给前台页面,这样的做法实在是很麻烦,每一次使用都要写数行代码,所以还是决定继续使用jackson来实现自动转化。使用方法很简单:

 
<pre>`
@RequiresPermissions("visit_arrangement:manage")
@RequestMapping("/tour_route/save.do")
@ResponseBody
public ModelMap save(TourRoute bean, HttpServletRequest request) {
    ModelMap model = new ModelMap();
    WebErrors errors = validateSave(bean, request);
    if (errors.hasErrors()) {
        model.addAttribute("errors", errors.getErrors());
        model.addAttribute("Status", false);
    }else{
        if(bean.getPreDefined() == null){
            bean.setPreDefined(BaseTourRoute.IS_PRE_DEFINED);
        }
        bean.setIsEffective(BaseCommonEntity.EFFECTIVE_TRUE);
        bean = manager.save(bean);
        model.addAttribute("Status", true);
        log.info("save TourRoute id={}", bean.getId());            
    }
    return model;
}

只需要在方法上方加上@ResponseBody注解就可以了。

但是今天在使用这种方式的时候出现了问题,因为一些问题,jackson在转化对象的时候报错,初步估计是因为JEECMS使用hibernate的延迟加载问题,好在所需要加载的属性是一些无关紧要的内容,所以上网上找到了解决方法:使用注解过滤掉不需要的属性就可以了,这里也正式学习一些jackson2常用的注解。

1.@JsonIgnoreProperties

主要作用于类,可以忽略类中指定的属性(在序列号和反序列化都起作用)。用例:@JsonIgnoreProperties (value = { “hibernateLazyInitializer” , “password” })

这里的用例中包含了“hibernateLazyInitializer”,作用就是忽略hibernate延迟加载的属性。因为hibernate会给被管理的pojo加入一个hibernateLazyInitializer属性,jackson会把hibernateLazyInitializer也拿出来操作,并读取里面一个不能被反射操作的属性就产生了异常。

以上斜体段落摘自a57565587的博文《@JsonIgnoreProperties(value={“hibernateLazyInitializer”}) 属性》,这也就解释了为什么我在用jackson时会出现错误,只要使用该注解忽略掉无法读取的属性就可以了。(根本上的解决方法:http://stackoverflow.com/questions/21708339/avoid-jackson-serialization-on-non-fetched-lazy-objects,今天太晚,以后有空研究)

第二个忽略的属性是”password”,这个也是我没有注意到的一点,jackson很方便,所以在使用时很容易忘记对关键数据的保护,一旦传到前台很容易造成用户信息泄漏。

2.@JsonIgnore

此注解用于属性或者方法上(最好是属性上),作用和上面的@JsonIgnoreProperties一样。

3.@JsonFormat

此注解用于属性或者方法上(最好是属性上),可以方便的把Date类型直接转化为我们想要的模式,比如@JsonFormat(pattern = “yyyy-MM-dd HH-mm-ss”),至于其他类型是否能够转化还有待研究。这里想到前面写过的一片博文《使用JQGrid开发过程中遇到的一些问题》,在该文章中因为jqgrid的时间格式化无法使用,所以我选择了修改jqgrid源码,其实也可以使用@JsonFormat注解将数据直接格式化,当然两种方法各有优势。

4.@JsonSerialize和@JsonDeserialize

这两个注解我感觉并不是特别常用,所以留到以后再看。

以上的注解参考自《Json解析工具Jackson(使用注解)》。