zoukankan      html  css  js  c++  java
  • hibernate懒加载导致jackjson解析json时StackOverFlow

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

    [java] view plain copy
     
    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.   
    7.      @ManyToOne(fetch=FetchType.LAZY)  
    8.      @JoinColumn(name="parent_id",referencedColumnName="id")  
    9.      public Module parent;  
    10. }  
    
    
    
    
    

    @JsonFilter用法

    [java] view plain copy
     
    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.   
    7.      @ManyToOne(fetch=FetchType.LAZY)  
    8.      @JoinColumn(name="parent_id",referencedColumnName="id")  
    9.      public Module parent;  
    10. }  
    [java] view plain copy
     
    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,请看下面的代码:

    [java] view plain copy
     
    1. package com.company.project.common.util;  
    2.   
    3. import java.util.Map;  
    4. import java.util.Map.Entry;  
    5. import java.util.Set;  
    6.   
    7. import com.alibaba.fastjson.JSON;  
    8. import com.alibaba.fastjson.serializer.JSONSerializer;  
    9. import com.alibaba.fastjson.serializer.PropertyFilter;  
    10. import com.alibaba.fastjson.serializer.SerializeWriter;  
    11. import com.alibaba.fastjson.serializer.SerializerFeature;  
    12.   
    13. public class JsonHelpler {  
    14.           
    15.         public static String toJSON(Object o){  
    16.             return JSON.toJSONString(o,SerializerFeature.WriteMapNullValue);  
    17.         }  
    18.   
    19.          public static SerializeWriter toJSON(Object obj, final Map<Class<?>, Set<String>> includeMap){  
    20.              PropertyFilter filter = new PropertyFilter() {  
    21.                 @Override  
    22.                 public boolean apply(Object source, String name, Object value) {  
    23.                     for(Entry<Class<?>, Set<String>> entry : includeMap.entrySet()) {    
    24.                         Class<?> class1 = entry.getKey();    
    25.                         if(source.getClass() == class1){    
    26.                             Set<String> fields = entry.getValue();    
    27.                             for(String field : fields) {    
    28.                                 if(field.equals(name)){    
    29.                                     return false;    
    30.                                 }    
    31.                             }    
    32.                         }    
    33.                     }  
    34.                     return true;   
    35.                 } };  
    36.                 SerializeWriter sw = new SerializeWriter();   
    37.                 JSONSerializer serializer = new JSONSerializer(sw);  
    38.                 serializer.getPropertyFilters().add(filter);  
    39.                 serializer.write(obj);  
    40.                 return sw;  
    41.          }  
    42.            
    43. }  
    44.   
    45. 测试代码  
    46. Map<Class<?>, Set<String>> includeMap =  new HashMap<Class<?>, Set<String>>();  
    47. Set<String> set = new HashSet<String>();  
    48. set.add("parent");  
    49. set.add("models");  
    50. includeMap.put(Module.class, set);  
    51. SerializeWriter resultString=JsonHelpler.toJSON(module, includeMap);  
    52. System.out.println(resultString);  
  • 相关阅读:
    LoadRunner最新版本11.5
    NeoLoad 4.1 号称第一款全面支持移动性能测试的工具
    【广州】QTP自动化测试实战训练
    Oracle动态性能视图V$SESSION_LONGOPS
    Oracle体系(转)
    DBMS学习(一)
    C#类和接口、虚方法和抽象方法及值类型和引用类型的区别
    .NET下读取PDF文本总结[转]
    处女篇
    网站开发周期
  • 原文地址:https://www.cnblogs.com/zhengshiqiang47/p/6754213.html
Copyright © 2011-2022 走看看