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

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

     <!-- json -->

         <!-- 1号 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.1</version>
</dependency>
<!-- 2号 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.1</version>
</dependency> <!-- 3号 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
<exclusions>
<exclusion>
<artifactId>jackson-core</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency> <!-- 4号 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
<!-- 5号 -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!-- 5号json-lib还需要以下依赖包 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>

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

Product.java

 package com.agen.entity;

 import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient; import org.hibernate.annotations.GenericGenerator; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.google.gson.annotations.Expose; /**
* Product entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "product", catalog = "biologyinfo") public class Product implements java.io.Serializable { private static final long serialVersionUID = 1L;
private String productId;
private String productName;
private String productPath;
private Integer productOrder;
private String productCre;
private Set<Disease> diseases = new HashSet<Disease>(0); // Constructors /** default constructor */
public Product() {
} /** full constructor */
public Product(String productName, String productPath,
Integer productOrder, String productCre, Set<Disease> diseases) {
this.productName = productName;
this.productPath = productPath;
this.productOrder = productOrder;
this.productCre = productCre;
this.diseases = diseases;
} // Property accessors
@GenericGenerator(name = "generator", strategy = "uuid.hex")
@Id
@GeneratedValue(generator = "generator")
@Column(name = "productId", unique = true, nullable = false, length = 36)
public String getProductId() {
return this.productId;
} public void setProductId(String productId) {
this.productId = productId;
} @Column(name = "productName", length = 30)
public String getProductName() {
return this.productName;
} public void setProductName(String productName) {
this.productName = productName;
} @Column(name = "productPath", length = 200)
public String getProductPath() {
return this.productPath;
} public void setProductPath(String productPath) {
this.productPath = productPath;
} @Column(name = "productOrder")
public Integer getProductOrder() {
return this.productOrder;
} public void setProductOrder(Integer productOrder) {
this.productOrder = productOrder;
} @Column(name = "productCre", length = 500)
public String getProductCre() {
return this.productCre;
} public void setProductCre(String productCre) {
this.productCre = productCre;
} @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "product")
public Set<Disease> getDiseases() {
return this.diseases;
} public void setDiseases(Set<Disease> diseases) {
this.diseases = diseases;
} }

Disease.java

 package com.agen.entity;

 import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.google.gson.annotations.Expose; /**
* Disease entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "disease", catalog = "biologyinfo")
@JsonIgnoreProperties(value = {"product"})
public class Disease implements java.io.Serializable { /**
*
*/
private static final long serialVersionUID = 1L;
private String diseaseId;
private transient Product product;
private String diseaseName;
private String diseasePath;
private Integer diseaseOrder;
private String diseaseCre;
private Set<Filelist> filelists = new HashSet<Filelist>(0);
private Set<Gene> genes = new HashSet<Gene>(0); // Constructors /** default constructor */
public Disease() {
} /** minimal constructor */
public Disease(Product product) {
this.product = product;
} /** full constructor */
public Disease(Product product, String diseaseName, String diseasePath,
Integer diseaseOrder, String diseaseCre, Set<Filelist> filelists,
Set<Gene> genes) {
this.product = product;
this.diseaseName = diseaseName;
this.diseasePath = diseasePath;
this.diseaseOrder = diseaseOrder;
this.diseaseCre = diseaseCre;
this.filelists = filelists;
this.genes = genes;
} // Property accessors
@GenericGenerator(name = "generator", strategy = "uuid.hex")
@Id
@GeneratedValue(generator = "generator")
@Column(name = "diseaseId", unique = true, nullable = false, length = 36)
public String getDiseaseId() {
return this.diseaseId;
} public void setDiseaseId(String diseaseId) {
this.diseaseId = diseaseId;
} @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "productId", nullable = false)
public Product getProduct() {
return this.product;
} public void setProduct(Product product) {
this.product = product;
} @Column(name = "diseaseName", length = 30)
public String getDiseaseName() {
return this.diseaseName;
} public void setDiseaseName(String diseaseName) {
this.diseaseName = diseaseName;
} @Column(name = "diseasePath", length = 200)
public String getDiseasePath() {
return this.diseasePath;
} public void setDiseasePath(String diseasePath) {
this.diseasePath = diseasePath;
} @Column(name = "diseaseOrder")
public Integer getDiseaseOrder() {
return this.diseaseOrder;
} public void setDiseaseOrder(Integer diseaseOrder) {
this.diseaseOrder = diseaseOrder;
} @Column(name = "diseaseCre", length = 500)
public String getDiseaseCre() {
return this.diseaseCre;
} public void setDiseaseCre(String diseaseCre) {
this.diseaseCre = diseaseCre;
} @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "disease")
public Set<Filelist> getFilelists() {
return this.filelists;
} public void setFilelists(Set<Filelist> filelists) {
this.filelists = filelists;
} @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "disease")
public Set<Gene> getGenes() {
return this.genes;
} public void setGenes(Set<Gene> genes) {
this.genes = genes;
} }

第一种方法:

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

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

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

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

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

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

第二种方法:

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

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

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

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

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

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

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

声明:

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

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

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

  1. Atitit.json xml 序列化循环引用解决方案json

    Atitit.json xml 序列化循环引用解决方案json 1. 循环引用1 2. 序列化循环引用解决方法1 2.1. 自定义序列化器1 2.2. 排除策略1 2.3. 设置序列化层次,一般3级别 ...

  2. 解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

    1..Net开源Json序列化工具Newtonsoft.Json中提供了解决序列化的循环引用问题: 方式1:指定Json序列化配置为 ReferenceLoopHandling.Ignore 方式2: ...

  3. 【JSON 注解】JSON循环引用1-----Jackson常用注解介绍 eq:@JsonIgnore

    循环引用:实体A与实体B有关系,A中有B作为字段,B中有A作为一个字段.查询A对象后,将A对象转化为JSON格式数据时,会因为序列化过程中导致A中有B字段,B字段中又有A,这样就引起了循环引用的问题! ...

  4. 用JSON.stringify处理循环引用对象

    通常,我们会用JSON.stringify把Javascript对象序列化成JSON格式,这在大多数情况下是够用的.但是,当你要转换的对象里存在循环引用时,问题就来了. js对象循环引用导致内存泄漏 ...

  5. EntityFramework中Json序列化的循环引用问题解决--Newtonsoft.Json

    1.在使用EF时,由于数据库主外键关联,将对象进行Json序列化时会遇到循环引用的问题 //EF 中由于数据库主外键关联,对象的序列化经常出现循环引用问题 //使用.Net 自带的序列化工具,序列化出 ...

  6. 使用 EntityFramework后把一个对象序列化成json字符串引起循环引用的问题

    先看一个T4模板生成的model实体类 著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:卷猫 链接:http://anneke.cn/ArticleInfo/Detial ...

  7. EF 序列化实体为Json时的循环引用问题(不用自己写实体,不用匿名类型,不用EF的上下文属性)

    自己写实体可以完美解决这个问题.(支持时间格式自定义) 用匿名类型也可以. 设置上下文方法如下: (jz为数据库上下文对象) jz.Configuration.ProxyCreationEnabled ...

  8. springMvc-对servletApi的支持以及把后台对象以json方式传到前台

    1.对servletApi的支持:request.response以及session.cookie的支持 2.把后台代码以json格式向前台输出: 代码: package com.java.contr ...

  9. java基础之泛型对象与json互转

    1. 场景描述 把泛型对象转成字符串放到缓存中,获取后使用有点问题,记录下,有碰到的朋友,参考下. 2. 解决方案 2.1 操作类及说明 /** * @auther: 软件老王 */ public s ...

随机推荐

  1. Mac下安装MySQL

    2015-07-13 15:10:32 Mac下用homebrew安装软件还是很方便的 brew install mysql 等待一会儿安装完毕后到安装目录: /usr/local/Cellar/my ...

  2. Word转图片(使用Spire.doc)

    Spire.Doc for .NET是一款由E-iceblue公司开发的专业的Word .NET类库.支持.net,WPF,Silverlight, 下载地址:http://www.e-iceblue ...

  3. Python—>Mysql—>Dbvisualizer

    MySQLdb: https://pypi.python.org/pypi/MySQL-python/1.2.4 import MySQLdb 1.Download Connector/Python: ...

  4. 两个oracle之间建立db link

    create database link tobsms connect to bjlt identified by bjlt using '(DESCRIPTION = (ADDRESS_LIST = ...

  5. 【python】Python遍历dict的key最高效的方法是什么?

    来源:https://segmentfault.com/q/1010000002581747 方法一:直接遍历 速度快 for key in _dict: pass 方法二:iterkeys() 速度 ...

  6. LeetCode 453 Minimum Moves to Equal Array Elements

    Problem: Given a non-empty integer array of size n, find the minimum number of moves required to mak ...

  7. ACdream 1224 Robbers (贪心)

    一道贪心题,很久前做的,代码是我以前写的. 题意:有n个抢劫者抢劫了m块金子,然后第i个人平分xi/y块金子,但是会有除不尽的情况而金子不可再分,那么每个人都有一个不满意度fabs(xi / y - ...

  8. [Android Pro] synchronized与static synchronized 的区别

    reference to :  http://www.cnblogs.com/shipengzhi/articles/2223100.html 1.synchronized与static synchr ...

  9. 用线框模式绘制多边形 glPolygonMode

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_TRIANGLES);//开始以g_ViewMode模式绘制 glColor3ub(182. ...

  10. Scrapy爬取美女图片 (原创)

    有半个月没有更新了,最近确实有点忙.先是华为的比赛,接着实验室又有项目,然后又学习了一些新的知识,所以没有更新文章.为了表达我的歉意,我给大家来一波福利... 今天咱们说的是爬虫框架.之前我使用pyt ...