zoukankan      html  css  js  c++  java
  • jackson java转json hibernate懒加载造成的无限递归问题

    @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 用法

    1. //忽略parent models属性
    2. @JsonIgnoreProperties({"parent","models"})
    3. public class Module{
    4. @OneToMany(fetch=FetchType.LAZY,mappedBy="parent",cascade=CascadeType.REMOVE)
    5. public java.util.List<Module> models;
    6. @ManyToOne(fetch=FetchType.LAZY)
    7. @JoinColumn(name="parent_id",referencedColumnName="id")
    8. public Module parent;
    9. }
    
    
    
    


    @JsonFilter用法

    1. //忽略parent models属性
    2. @JsonFilter("module")
    3. public class Module{
    4. @OneToMany(fetch=FetchType.LAZY,mappedBy="parent",cascade=CascadeType.REMOVE)
    5. public java.util.List<Module> models;
    6. @ManyToOne(fetch=FetchType.LAZY)
    7. @JoinColumn(name="parent_id",referencedColumnName="id")
    8. public Module parent;
    9. }
    1. 测试代码:
    2. Module module=moduleService.findModuleByName("文件管理");
    3. ObjectMapper mapper=new ObjectMapper();
    4. FilterProvider filterProvider=new SimpleFilterProvider().addFilter("module", SimpleBeanPropertyFilter.serializeAllExcept("parent","models"));
    5. mapper.setFilters(filterProvider);
    6. String resultString=mapper.writeValueAsString(module);

    
    

    
    

    JsonFilter可以动态指定过滤的属性,缺点:每次转换都要设置过滤器,否则会报错,就这点很不爽。既然不爽就换种方式过滤,使用fastjson,请看下面的代码:

    1. package com.company.project.common.util;
    2. import java.util.Map;
    3. import java.util.Map.Entry;
    4. import java.util.Set;
    5. import com.alibaba.fastjson.JSON;
    6. import com.alibaba.fastjson.serializer.JSONSerializer;
    7. import com.alibaba.fastjson.serializer.PropertyFilter;
    8. import com.alibaba.fastjson.serializer.SerializeWriter;
    9. import com.alibaba.fastjson.serializer.SerializerFeature;
    10. public class JsonHelpler {
    11. public static String toJSON(Object o){
    12. return JSON.toJSONString(o,SerializerFeature.WriteMapNullValue);
    13. }
    14. public static SerializeWriter toJSON(Object obj, final Map<Class<?>, Set<String>> includeMap){
    15. PropertyFilter filter = new PropertyFilter() {
    16. @Override
    17. public boolean apply(Object source, String name, Object value) {
    18. for(Entry<Class<?>, Set<String>> entry : includeMap.entrySet()) {
    19. Class<?> class1 = entry.getKey();
    20. if(source.getClass() == class1){
    21. Set<String> fields = entry.getValue();
    22. for(String field : fields) {
    23. if(field.equals(name)){
    24. return false;
    25. }
    26. }
    27. }
    28. }
    29. return true;
    30. } };
    31. SerializeWriter sw = new SerializeWriter();
    32. JSONSerializer serializer = new JSONSerializer(sw);
    33. serializer.getPropertyFilters().add(filter);
    34. serializer.write(obj);
    35. return sw;
    36. }
    37. }
    38. 测试代码
    39. Map<Class<?>, Set<String>> includeMap = new HashMap<Class<?>, Set<String>>();
    40. Set<String> set = new HashSet<String>();
    41. set.add("parent");
    42. set.add("models");
    43. includeMap.put(Module.class, set);
    44. SerializeWriter resultString=JsonHelpler.toJSON(module, includeMap);
    45. System.out.println(resultString);



    原文地址:https://blog.csdn.net/cym19890801/article/details/49660105
  • 相关阅读:
    java的构造方法 this 重载
    容器,组件,面板
    首先定义一个5X8的二维数组,然后使用随机数填充满。借助Arrays的方法对二维数组进行排序。
    首先创建一个长度是5的数组,并填充随机数。首先用选择法正排序,然后再对其使用冒泡法倒排序
    创建一个长度是5的数组,并填充随机数。使用for循环或者while循环,对这个数组实现反转效果
    寻找某两个数相除,其结果 离黄金分割点 0.618最近,分母和分子不能同时为偶数 * 分母和分子 取值范围在[1-20]
    密码的自动生成器:密码由大写字母/小写字母/数字组成,生成12位随机密码
    vue倒计时:天时分秒
    tbody设置超出固定的高度出现滚动条,没超出不显示。
    获取某个日期的当前周一的时间
  • 原文地址:https://www.cnblogs.com/jpfss/p/11063585.html
Copyright © 2011-2022 走看看