zoukankan      html  css  js  c++  java
  • 【JSON 注解】JSON循环引用2----JSON注解@JsonIgnoreProperties+JAVA关键字transient+后台对象与JSON数据的格式互相转化

    接着来说这个JSON循环引用的问题:

    关于JSON格式的转化,其实关键就是这几个依赖:

     1     <!-- json -->
     2 
     3         <!-- 1号 -->
     4         <dependency>
     5             <groupId>com.fasterxml.jackson.core</groupId>
     6             <artifactId>jackson-core</artifactId>
     7             <version>2.8.1</version>
     8         </dependency>
     9         <!-- 2号 -->
    10         <dependency>
    11             <groupId>com.fasterxml.jackson.core</groupId>
    12             <artifactId>jackson-annotations</artifactId>
    13             <version>2.8.1</version>
    14         </dependency>
    15 
    16         <!-- 3号 -->
    17         <dependency>
    18             <groupId>com.fasterxml.jackson.core</groupId>
    19             <artifactId>jackson-databind</artifactId>
    20             <version>2.8.1</version>
    21             <exclusions>
    22                 <exclusion>
    23                     <artifactId>jackson-core</artifactId>
    24                     <groupId>com.fasterxml.jackson.core</groupId>
    25                 </exclusion>
    26                 <exclusion>
    27                     <artifactId>jackson-annotations</artifactId>
    28                     <groupId>com.fasterxml.jackson.core</groupId>
    29                 </exclusion>
    30             </exclusions>
    31         </dependency>
    32 
    33         <!-- 4号 -->
    34         <dependency>
    35             <groupId>com.google.code.gson</groupId>
    36             <artifactId>gson</artifactId>
    37             <version>2.7</version>
    38         </dependency>
    39         <!-- 5号 -->
    40         <dependency>
    41             <groupId>net.sf.json-lib</groupId>
    42             <artifactId>json-lib</artifactId>
    43             <version>2.4</version>
    44             <classifier>jdk15</classifier>
    45         </dependency>
    46         <!-- 5号json-lib还需要以下依赖包 -->
    47         <dependency>
    48             <groupId>commons-lang</groupId>
    49             <artifactId>commons-lang</artifactId>
    50             <version>2.5</version>
    51         </dependency>
    52         <dependency>
    53             <groupId>commons-beanutils</groupId>
    54             <artifactId>commons-beanutils</artifactId>
    55             <version>1.9.2</version>
    56         </dependency>
    57         <dependency>
    58             <groupId>commons-collections</groupId>
    59             <artifactId>commons-collections</artifactId>
    60             <version>3.2.1</version>
    61         </dependency>
    62         <dependency>
    63             <groupId>commons-logging</groupId>
    64             <artifactId>commons-logging</artifactId>
    65             <version>1.2</version>
    66         </dependency>
    View Code

    如果要解决查询出来实体 将实体转换为JSON数据的问题,Product产品类:Disease疾病类(1:n)这两个实体类正确写法如下:

    Product.java

      1 package com.agen.entity;
      2 
      3 import java.util.HashSet;
      4 import java.util.Set;
      5 
      6 import javax.persistence.CascadeType;
      7 import javax.persistence.Column;
      8 import javax.persistence.Entity;
      9 import javax.persistence.FetchType;
     10 import javax.persistence.GeneratedValue;
     11 import javax.persistence.Id;
     12 import javax.persistence.OneToMany;
     13 import javax.persistence.Table;
     14 import javax.persistence.Transient;
     15 
     16 import org.hibernate.annotations.GenericGenerator;
     17 
     18 import com.fasterxml.jackson.annotation.JsonIgnore;
     19 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
     20 import com.google.gson.annotations.Expose;
     21 
     22 /**
     23  * Product entity. @author MyEclipse Persistence Tools
     24  */
     25 @Entity
     26 @Table(name = "product", catalog = "biologyinfo")
     27 
     28 public class Product implements java.io.Serializable {
     29 
     30     private static final long serialVersionUID = 1L;
     31     private String productId;
     32     private String productName;
     33     private String productPath;
     34     private Integer productOrder;
     35     private String productCre;
     36     private Set<Disease> diseases = new HashSet<Disease>(0);
     37 
     38     // Constructors
     39 
     40     /** default constructor */
     41     public Product() {
     42     }
     43 
     44     /** full constructor */
     45     public Product(String productName, String productPath,
     46             Integer productOrder, String productCre, Set<Disease> diseases) {
     47         this.productName = productName;
     48         this.productPath = productPath;
     49         this.productOrder = productOrder;
     50         this.productCre = productCre;
     51         this.diseases = diseases;
     52     }
     53 
     54     // Property accessors
     55     @GenericGenerator(name = "generator", strategy = "uuid.hex")
     56     @Id
     57     @GeneratedValue(generator = "generator")
     58     @Column(name = "productId", unique = true, nullable = false, length = 36)
     59     public String getProductId() {
     60         return this.productId;
     61     }
     62 
     63     public void setProductId(String productId) {
     64         this.productId = productId;
     65     }
     66 
     67     @Column(name = "productName", length = 30)
     68     public String getProductName() {
     69         return this.productName;
     70     }
     71 
     72     public void setProductName(String productName) {
     73         this.productName = productName;
     74     }
     75 
     76     @Column(name = "productPath", length = 200)
     77     public String getProductPath() {
     78         return this.productPath;
     79     }
     80 
     81     public void setProductPath(String productPath) {
     82         this.productPath = productPath;
     83     }
     84 
     85     @Column(name = "productOrder")
     86     public Integer getProductOrder() {
     87         return this.productOrder;
     88     }
     89 
     90     public void setProductOrder(Integer productOrder) {
     91         this.productOrder = productOrder;
     92     }
     93 
     94     @Column(name = "productCre", length = 500)
     95     public String getProductCre() {
     96         return this.productCre;
     97     }
     98 
     99     public void setProductCre(String productCre) {
    100         this.productCre = productCre;
    101     }
    102 
    103     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "product")
    104     public Set<Disease> getDiseases() {
    105         return this.diseases;
    106     }
    107 
    108     public void setDiseases(Set<Disease> diseases) {
    109         this.diseases = diseases;
    110     }
    111 
    112 
    113 }
    View Code

    Disease.java

      1 package com.agen.entity;
      2 
      3 import java.util.HashSet;
      4 import java.util.Set;
      5 
      6 import javax.persistence.CascadeType;
      7 import javax.persistence.Column;
      8 import javax.persistence.Entity;
      9 import javax.persistence.FetchType;
     10 import javax.persistence.GeneratedValue;
     11 import javax.persistence.Id;
     12 import javax.persistence.JoinColumn;
     13 import javax.persistence.ManyToOne;
     14 import javax.persistence.OneToMany;
     15 import javax.persistence.Table;
     16 
     17 import org.hibernate.annotations.GenericGenerator;
     18 
     19 import com.fasterxml.jackson.annotation.JsonIgnore;
     20 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
     21 import com.google.gson.annotations.Expose;
     22 
     23 /**
     24  * Disease entity. @author MyEclipse Persistence Tools
     25  */
     26 @Entity
     27 @Table(name = "disease", catalog = "biologyinfo")
     28 @JsonIgnoreProperties(value = {"product"})
     29 public class Disease implements java.io.Serializable {
     30 
     31 
     32     /**
     33      * 
     34      */
     35     private static final long serialVersionUID = 1L;
     36     private String diseaseId;
     37     private transient Product product;
     38     private String diseaseName;
     39     private String diseasePath;
     40     private Integer diseaseOrder;
     41     private String diseaseCre;
     42     private Set<Filelist> filelists = new HashSet<Filelist>(0);
     43     private Set<Gene> genes = new HashSet<Gene>(0);
     44 
     45     // Constructors
     46 
     47     /** default constructor */
     48     public Disease() {
     49     }
     50 
     51     /** minimal constructor */
     52     public Disease(Product product) {
     53         this.product = product;
     54     }
     55 
     56     /** full constructor */
     57     public Disease(Product product, String diseaseName, String diseasePath,
     58             Integer diseaseOrder, String diseaseCre, Set<Filelist> filelists,
     59             Set<Gene> genes) {
     60         this.product = product;
     61         this.diseaseName = diseaseName;
     62         this.diseasePath = diseasePath;
     63         this.diseaseOrder = diseaseOrder;
     64         this.diseaseCre = diseaseCre;
     65         this.filelists = filelists;
     66         this.genes = genes;
     67     }
     68 
     69     // Property accessors
     70     @GenericGenerator(name = "generator", strategy = "uuid.hex")
     71     @Id
     72     @GeneratedValue(generator = "generator")
     73     @Column(name = "diseaseId", unique = true, nullable = false, length = 36)
     74     public String getDiseaseId() {
     75         return this.diseaseId;
     76     }
     77 
     78     public void setDiseaseId(String diseaseId) {
     79         this.diseaseId = diseaseId;
     80     }
     81 
     82     @ManyToOne(fetch = FetchType.LAZY)
     83     @JoinColumn(name = "productId", nullable = false)
     84     public Product getProduct() {
     85         return this.product;
     86     }
     87 
     88     public void setProduct(Product product) {
     89         this.product = product;
     90     }
     91 
     92     @Column(name = "diseaseName", length = 30)
     93     public String getDiseaseName() {
     94         return this.diseaseName;
     95     }
     96 
     97     public void setDiseaseName(String diseaseName) {
     98         this.diseaseName = diseaseName;
     99     }
    100 
    101     @Column(name = "diseasePath", length = 200)
    102     public String getDiseasePath() {
    103         return this.diseasePath;
    104     }
    105 
    106     public void setDiseasePath(String diseasePath) {
    107         this.diseasePath = diseasePath;
    108     }
    109 
    110     @Column(name = "diseaseOrder")
    111     public Integer getDiseaseOrder() {
    112         return this.diseaseOrder;
    113     }
    114 
    115     public void setDiseaseOrder(Integer diseaseOrder) {
    116         this.diseaseOrder = diseaseOrder;
    117     }
    118 
    119     @Column(name = "diseaseCre", length = 500)
    120     public String getDiseaseCre() {
    121         return this.diseaseCre;
    122     }
    123 
    124     public void setDiseaseCre(String diseaseCre) {
    125         this.diseaseCre = diseaseCre;
    126     }
    127 
    128     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "disease")
    129     public Set<Filelist> getFilelists() {
    130         return this.filelists;
    131     }
    132 
    133     public void setFilelists(Set<Filelist> filelists) {
    134         this.filelists = filelists;
    135     }
    136 
    137     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "disease")
    138     public Set<Gene> getGenes() {
    139         return this.genes;
    140     }
    141 
    142     public void setGenes(Set<Gene> genes) {
    143         this.genes = genes;
    144     }
    145 
    146 }
    View Code

    第一种方法:

    如上面的Disease.java实体类的类上添加了@JsonIgnoreProperties(value = {"product"})

    这个表明 ,现在是在Disease对象的product字段上进行循环引用的隔断。

    那么查询的时候,查询Product实体,其中的的disease这个字段是有值的;但是查询Disease实体,其中的product字段是没有值的,因为这个注解在Disease.java类上进行的注解。

    同理,如果将这个注解加在哪个实体上,指定了哪个字段就是在哪个字段上阻断。

    那么此时的Controller中,我要查询Product对象,并且要将查询出来的对象转化为JSON格式的数据:

     1 @RequestMapping("/disease")
     2     public String checkdisease(String productId, ModelMap model)
     3             throws IOException {
     4         Product product = productService.get(productId);
     5         //将对象转化为JSON字符串
     6         //方法1  com.fasterxml.jackson.databind.ObjectMapper  使用3号架包
     7         ObjectMapper mapper = new ObjectMapper();
     8         String json = mapper.writeValueAsString(product);
     9         model.addAttribute("product", json);
    10         
    11         //将JSON字符串 转化为对象[只是在此将方法列出,并无实际意义]
    12         //com.fasterxml.jackson.databind.ObjectMapper  使用3号架包
    13         Product product2 = mapper.readValue(json, Product.class);
    14         
    15         return "/geneinfo/disease/disease";
    16     }
    View Code

    第二种方法:

    如上面的Disease.java实体类上添加了Java的关键字   transient

    使用transient关键字的作用在于:变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问

    这个也是阻断循环引用的一种方法。

    同样的,查询Product实体,其中的的disease这个字段是有值的;但是查询Disease实体,其中的product字段是没有值的,因为这个关键字在Disease.java类的product字段上加的。

    同理,将这个关键字加在那个字段上 就是在哪个字段上阻断。

    那么 此时的Controller中,我们要查询Product对象,并且要将查询出来的对象转化为JSON格式的数据:

     1 @RequestMapping("/disease")
     2     public String checkdisease(String productId, ModelMap model)
     3             throws IOException {
     4         Product product = productService.get(productId);
     5         //将对象转化为JSON字符串
     6         //方法1 com.google.gson.Gson 使用4号架包
     7         String json1 = new Gson().toJson(product);
     8         model.addAttribute("product", json1);
     9         return "/geneinfo/disease/disease";
    10     }
    View Code

    声明:

    上面的两种方法中 ,分别采用哪个架包中的哪个类,标识的很明白了。

    但是由于Spring框架默认的是采用 com.fasterxml.jackson.annotation进行JSON的转化,所以我们第一种方法中的@JsonIgnoreProperties(value = {"product"})注解必须要添加在实体上

    第二种中的transient关键字是和采用com.google.gson.Gson 谷歌提供的这个架包中的方法配套使用,如果不使用第二种方法进行对象转化JSON格式的数据,可以不用在字段上添加关键字

    声明2:

    //net.sf.json.JSONObject
    JSONObject.fromObject(product2).toString();

    这种将Object转化为JSON数据的方法比较常见,但是它这个架包识别不到@JsonIgnoreProperties这个注解,因为他们不是同一个架包,不是同一个规范,所以在转化JSON的时候,会发生循环引用的问题。

    因此这里不采用这种方式转化!!!

    一个学习关键字transient的好文章 给大家推荐:http://www.cnblogs.com/lanxuezaipiao/p/3369962.html

    当然使用了这两种的方法之后,就不用采用@JsonIgnore了。

  • 相关阅读:
    TCP/IP 13学习笔记
    代码注入的三种方法
    一个简单的GTK的例子程序
    打印同样一个数据,竟然出现不同的结果,解决方法。
    解决multiple definition of的方法
    anjuta的安装、配置以及第一个hello程序
    rhythmbox中文乱码的解决方法
    Windows 和 Linux开发工具对比
    debian(包括ubuntu)命令行下的中文支持
    如何解决warning: no newline at end of file?
  • 原文地址:https://www.cnblogs.com/sxdcgaq8080/p/5772784.html
Copyright © 2011-2022 走看看