1. 程式人生 > >【JSON 註解】JSON迴圈引用2----JSON註解@JsonIgnoreProperties+JAVA關鍵字transient+後臺物件與JSON資料的格式互相轉化

【JSON 註解】JSON迴圈引用2----JSON註解@JsonIgnoreProperties+JAVA關鍵字transient+後臺物件與JSON資料的格式互相轉化

接著來說這個JSON迴圈引用的問題:

@JsonIgnoreProperties({"hibernateLazyInitializer", "org","roles"})  在實體類上註解,在使用jackjson 來解析就行

參考下面

關於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>
複製程式碼

如果要解決查詢出來實體 將實體轉換為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 }
複製程式碼

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 }
複製程式碼

第一種方法:

如上面的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     }
複製程式碼

第二種方法:

如上面的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     }
複製程式碼

宣告:

上面的兩種方法中 ,分別採用哪個架包中的哪個類,標識的很明白了。

但是由於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了。