jackson java转json hibernate懒加载造成的无限递归问题
2015-11-05 11:11
531 查看
@JsonIgnore @JsonFilter @JsonBackReference @JsonManagedReference @JsonIgnoreProperties
jackson中的@JsonBackReference和@JsonManagedReference,以及@JsonIgnore均是为了解决对象中存在双向引用导致的无限递归(infinite recursion)问题。这些标注均可用在属性或对应的get、set方法中。
@JsonBackReference和@JsonManagedReference:这两个标注通常配对使用,通常用在父子关系中。@JsonBackReference标注的属性在序列化(serialization,即将对象转换为json数据)时,会被忽略(即结果中的json数据不包含该属性的内容)。@JsonManagedReference标注的属性则会被序列化。在序列化时,@JsonBackReference的作用相当于@JsonIgnore,此时可以没有@JsonManagedReference。但在反序列化(deserialization,即json数据转换为对象)时,如果没有@JsonManagedReference,则不会自动注入@JsonBackReference标注的属性(被忽略的父或子);如果有@JsonManagedReference,则会自动注入自动注入@JsonBackReference标注的属性。
@JsonIgnore:直接忽略某个属性,以断开无限递归,序列化或反序列化均忽略。当然如果标注在get、set方法中,则可以分开控制,序列化对应的是get方法,反序列化对应的是set方法。在父子关系中,当反序列化时,@JsonIgnore不会自动注入被忽略的属性值(父或子),这是它跟@JsonBackReference和@JsonManagedReference最大的区别。
@JsonIgnoreProperties 用法
@JsonFilter用法
JsonFilter可以动态指定过滤的属性,缺点:每次转换都要设置过滤器,否则会报错,就这点很不爽。既然不爽就换种方式过滤,使用fastjson,请看下面的代码:
jackson中的@JsonBackReference和@JsonManagedReference,以及@JsonIgnore均是为了解决对象中存在双向引用导致的无限递归(infinite recursion)问题。这些标注均可用在属性或对应的get、set方法中。
@JsonBackReference和@JsonManagedReference:这两个标注通常配对使用,通常用在父子关系中。@JsonBackReference标注的属性在序列化(serialization,即将对象转换为json数据)时,会被忽略(即结果中的json数据不包含该属性的内容)。@JsonManagedReference标注的属性则会被序列化。在序列化时,@JsonBackReference的作用相当于@JsonIgnore,此时可以没有@JsonManagedReference。但在反序列化(deserialization,即json数据转换为对象)时,如果没有@JsonManagedReference,则不会自动注入@JsonBackReference标注的属性(被忽略的父或子);如果有@JsonManagedReference,则会自动注入自动注入@JsonBackReference标注的属性。
@JsonIgnore:直接忽略某个属性,以断开无限递归,序列化或反序列化均忽略。当然如果标注在get、set方法中,则可以分开控制,序列化对应的是get方法,反序列化对应的是set方法。在父子关系中,当反序列化时,@JsonIgnore不会自动注入被忽略的属性值(父或子),这是它跟@JsonBackReference和@JsonManagedReference最大的区别。
@JsonIgnoreProperties 用法
//忽略parent models属性 @JsonIgnoreProperties({"parent","models"}) public class Module{ @OneToMany(fetch=FetchType.LAZY,mappedBy="parent",cascade=CascadeType.REMOVE) public java.util.List<Module> models; @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="parent_id",referencedColumnName="id") public Module parent; }
@JsonFilter用法
//忽略parent models属性 @JsonFilter("module") public class Module{ @OneToMany(fetch=FetchType.LAZY,mappedBy="parent",cascade=CascadeType.REMOVE) public java.util.List<Module> models; @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="parent_id",referencedColumnName="id") public Module parent; }
测试代码: Module module=moduleService.findModuleByName("文件管理"); ObjectMapper mapper=new ObjectMapper(); FilterProvider filterProvider=new SimpleFilterProvider().addFilter("module", SimpleBeanPropertyFilter.serializeAllExcept("parent","models")); mapper.setFilters(filterProvider); String resultString=mapper.writeValueAsString(module);
JsonFilter可以动态指定过滤的属性,缺点:每次转换都要设置过滤器,否则会报错,就这点很不爽。既然不爽就换种方式过滤,使用fastjson,请看下面的代码:
package com.company.project.common.util; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.PropertyFilter; import com.alibaba.fastjson.serializer.SerializeWriter; import com.alibaba.fastjson.serializer.SerializerFeature; public class JsonHelpler { public static String toJSON(Object o){ return JSON.toJSONString(o,SerializerFeature.WriteMapNullValue); } public static SerializeWriter toJSON(Object obj, final Map<Class<?>, Set<String>> includeMap){ PropertyFilter filter = new PropertyFilter() { @Override public boolean apply(Object source, String name, Object value) { for(Entry<Class<?>, Set<String>> entry : includeMap.entrySet()) { Class<?> class1 = entry.getKey(); if(source.getClass() == class1){ Set<String> fields = entry.getValue(); for(String field : fields) { if(field.equals(name)){ return false; } } } } return true; } }; SerializeWriter sw = new SerializeWriter(); JSONSerializer serializer = new JSONSerializer(sw); serializer.getPropertyFilters().add(filter); serializer.write(obj); return sw; } } 测试代码 Map<Class<?>, Set<String>> includeMap = new HashMap<Class<?>, Set<String>>(); Set<String> set = new HashSet<String>(); set.add("parent"); set.add("models"); includeMap.put(Module.class, set); SerializeWriter resultString=JsonHelpler.toJSON(module, includeMap); System.out.println(resultString);
相关文章推荐
- Java代码规范
- java学习4-继承
- JAVA的可变类与不可变类
- java中两种类型变量
- spring mvc 下 word 文档(含图片)导出
- java中怎么判断一个字符串中包含某个字符或字符串
- Swagger与SpringMVC项目整合
- JAVA 集合
- [异常] com.mysql.jdbc.ServerPreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V
- 最常用的 Eclipse 快捷键总结
- Java对象序列化
- Spring中的AOP—基于Annotation的配置方式
- Java 编程下的同步代码块
- java.lang.UnsupportedClassVersionError 解决办法
- SpringBoot学习(一)入门
- java体系技术日志
- 创建第一个Android工程-Eclipse创建Android项目
- CXF创建简单的RESTful 风格的webservice
- Eclipse SVN的使用
- Ubantu下创建eclipse快捷图标