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

简介: 接着来说这个JSON循环引用的问题: 关于JSON格式的转化,其实关键就是这几个依赖: 1 2 3 4 5 com.

接着来说这个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了。

 

相关文章
|
2月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
341 0
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
196 1
|
2月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
216 1
|
4月前
|
缓存 安全 Java
Java反射机制:动态操作类与对象
Java反射机制是运行时动态操作类与对象的强大工具,支持获取类信息、动态创建实例、调用方法、访问字段等。它在框架开发、依赖注入、动态代理等方面有广泛应用,但也存在性能开销和安全风险。本文详解反射核心API、实战案例及性能优化策略,助你掌握Java动态编程精髓。
|
4月前
|
存储 人工智能 JavaScript
Java从作用域到对象高级应用​
本内容详细讲解了JavaScript中的作用域类型(函数作用域、块作用域、全局作用域)、作用域链、垃圾回收机制、闭包、变量提升、函数参数、数组方法、内置构造函数、对象高级知识、原型链、对象赋值、深浅拷贝、递归、异常处理及this指向等内容,全面覆盖JS核心概念与编程技巧。
61 0
|
5月前
|
存储 Java
Java对象的内存布局
在HotSpot虚拟机中,Java对象的内存布局分为三部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。对象头包含Mark Word、Class对象指针及数组长度;实例数据存储对象的实际字段内容;对齐填充用于确保对象大小为8字节的整数倍。
120 0
|
6月前
|
Java 数据库连接 API
Java 对象模型现代化实践 基于 Spring Boot 与 MyBatis Plus 的实现方案深度解析
本文介绍了基于Spring Boot与MyBatis-Plus的Java对象模型现代化实践方案。采用Spring Boot 3.1.2作为基础框架,结合MyBatis-Plus 3.5.3.1进行数据访问层实现,使用Lombok简化PO对象,MapStruct处理对象转换。文章详细讲解了数据库设计、PO对象实现、DAO层构建、业务逻辑封装以及DTO/VO转换等核心环节,提供了一个完整的现代化Java对象模型实现案例。通过分层设计和对象转换,实现了业务逻辑与数据访问的解耦,提高了代码的可维护性和扩展性。
267 1
|
6月前
|
前端开发 Java 数据库连接
java bo 对象详解_全面解析 java 中 PO,VO,DAO,BO,POJO 及 DTO 等几种对象类型
Java开发中常见的六大对象模型(PO、VO、DAO、BO、POJO、DTO)各有侧重,共同构建企业级应用架构。PO对应数据库表结构,VO专为前端展示设计,DAO封装数据访问逻辑,BO处理业务逻辑,POJO是简单的Java对象,DTO用于层间数据传输。它们在三层架构中协作:表现层使用VO,业务层通过BO调用DAO处理PO,DTO作为数据传输媒介。通过在线商城的用户管理模块示例,展示了各对象的具体应用。最佳实践包括保持分层清晰、使用工具类转换对象,并避免过度设计带来的类膨胀。理解这些对象模型的区别与联系。
472 1
|
6月前
|
JSON IDE Java
鸿蒙开发:json转对象插件回来了
首先,我重新编译了插件,进行了上传,大家可以下载最新的安装包进行体验了,还是和以前一样,提供了在线版和IDE插件版,两个选择,最新的版本,除了升级了版本,兼容了最新的DevEco Studio ,还做了一层优化,就是针对嵌套对象和属性的生成,使用方式呢,一年前的文章中有过详细的概述,这里呢也简单介绍一下。
240 4
鸿蒙开发:json转对象插件回来了
|
7月前
|
Java
深入JavaSE:详解Java对象的比较。
总的来说,Java对象的比较就像海洋生物的比较,有外在的,有内在的,有面对所有情况的,也有针对特殊情况的。理解并掌握这些比较方式,就能更好地驾驭Java的世界,游刃有余地操作Java对象。
149 12