`
strong_fee
  • 浏览: 179208 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

Gson——循环引用的解决方案

    博客分类:
  • Java
阅读更多

Gson本身并不提供循环引用的直接解决方案。我们可以通过以下方式来解决循环引用的问题:

 

使用ava关键字transient

 

private transient int value = 3;

在序列化的时候value不会生成到json字符串中。

 

使用Gson提供的注解@Expose

 

@Exclude
private String value;

 

 当然,要使用这个属性必须通过以下语句来构造Gson对象

 

new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()

 我们也可以自定义注解来标注需要过滤的属性,参见官方的User Guide,需要使用到过滤策略,在下文也会提到。

 

使用排除策略

 

以上只能是通过“硬编码”的方式来排除属性,有些时候我们需要根据某种来选择性得过滤一些属性。这是我们可以使用使用Gson提供的排除策略ExclusionStrategy接口。如:

 

public class MyExclusionStrategy implements ExclusionStrategy {
    private MyExclusionStrategy(Class<?> typeToSkip) {
      
    }

    public boolean shouldSkipClass(Class<?> clazz) {
      return false;
    }

    public boolean shouldSkipField(FieldAttributes f) {
      return false;
    }
  }

 

我们可以通过类级别和属性级别来过滤属性。以上提到的关于自定义注解的实现是在属性级别上实现的。具体方法是

 

public boolean shouldSkipField(FieldAttributes f) {
      // Foo是一个自定义注解
      return f.getAnnotation(Foo.class) != null;
    }

 

一般情况下,我们可以通过根据属性名的判断来实现实现逻辑过滤。当然,在序列化之前,需要用一下代码来构造Gson对象:

 

 Gson gson = new GsonBuilder()
        .setExclusionStrategies(new MyExclusionStrategy(SomeObject.class))
        .create();

 

自定义序列化器 

在有些情况下,我们可能会为某一个类来绑定一种序列化或反序列化器。

 

public class MyAdaper1 implements JsonSerializer<DataStore> {

	@Override
	public JsonElement serialize(DataStore src, Type typeOfSrc,
			JsonSerializationContext context) {
		ExclusionStrategy strategy = new DmsExclusionStrategy(
				src.getExcludeFields(), src.getExcludeClasses());
		Gson gson = new GsonBuilder().setExclusionStrategies(strategy)
				.serializeNulls().create();
		return gson.toJsonTree(src);
	}
}

 注册序列化器:

 

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(MyType1.class, new MyTypeAdapter())
.registerTypeAdapter(MyType2.class, new MyTypeAdapter2());

 

最佳实践——综合使用自定义序列化器和排除策略

通常情况下,我们一下如下定义排除策略

 

public class DmsExclusionStrategy implements ExclusionStrategy {
	public DmsExclusionStrategy() {

	}

	public DmsExclusionStrategy(String[] excludeFields,
			Class<?>[] excludeClasses) {
		this.excludeFields = excludeFields;
		this.excludeClasses = excludeClasses;
	}

	private String[] excludeFields;
	private Class<?>[] excludeClasses;

	public boolean shouldSkipClass(Class<?> clazz) {
		if (this.excludeClasses == null) {
			return false;
		}

		for (Class<?> excludeClass : excludeClasses) {
			if (excludeClass.getName().equals(clazz.getName())) {
				return true;
			}
		}

		return false;
	}

	public boolean shouldSkipField(FieldAttributes f) {
		if (this.excludeFields == null) {
			return false;
		}

		for (String field : this.excludeFields) {
			if (field.equals(f.getName())) {
				return true;
			}
		}

		return false;
	}

	public final String[] getExcludeFields() {
		return excludeFields;
	}

	public final Class<?>[] getExcludeClasses() {
		return excludeClasses;
	}
}
 

定义一个排除模型:

 

 

public class Excludable {
	/**
	 * 不需要序列化的域.
	 */
	private transient String[] excludeFields;

	/**
	 * 不需要序列化的类.
	 */
	private transient Class<?>[] excludeClasses;

	public void setExcludeFields(String[] excludeFields) {
		this.excludeFields = excludeFields;
	}

	public String[] getExcludeFields() {
		return excludeFields;
	}

	public void setExcludeClasses(Class<?>[] excludeClasses) {
		this.excludeClasses = excludeClasses;
	}

	public Class<?>[] getExcludeClasses() {
		return excludeClasses;
	}
}
 

当我们需要为某个类应用过滤策略时,我们让这个类继承Excludable,自定义其相应的序列化器,在序列化的过程中应用排除策略。

 

public class MyTypeSerializer implements JsonSerializer<MyType> {

	@Override
	public JsonElement serialize(MyType src, Type typeOfSrc,
			JsonSerializationContext context) {
		ExclusionStrategy strategy = new DmsExclusionStrategy(
				src.getExcludeFields(), src.getExcludeClasses());
		Gson gson = new GsonBuilder().setExclusionStrategies(strategy)
				.serializeNulls().create();
		return gson.toJsonTree(src);
	}
}

 

 

分享到:
评论
3 楼 johlon 2012-04-26  
能不能发个Demo看看,谢谢!
2 楼 strong_fee 2012-03-16  
你可以从后台返回dept对象,这个对象里边包含emp集合。
1 楼 遇见的秘密花园 2012-03-15  
我没怎么看懂。。。我现在在做S2H集成的时候。遇到一个问题。dept 和 emp  我想点击部门名称时,异步显示 相应的emp 表的员工。可是,因为Hibernate会自动生成一些字段。。。我用@Util 把它过滤了。但是 我在JSP页面又要用到dept.dname 我该怎么办呀?

相关推荐

    gson-2.3.1的jar包含源码和说明文档

    例如,如何处理日期、如何处理复杂数据结构、如何处理循环引用等。 2. **示例代码**:文档中通常包含许多示例代码,展示如何使用Gson进行基本操作,如创建Gson对象、序列化和反序列化Java对象、处理特殊类型的转换...

    GSON JAR包 最新包和历史包 gson-2.10.1

    介绍:Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. 压缩包里有以下文件: ...

    Gson 2.3.1 jar包 ——官方下载

    Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice-versa Allow pre-existing unmodifiable objects to be converted to and from JSON Extensive support of Java ...

    om.google.gson.Gson Gson maven依赖

    Gson是Google开发的一款Java语言编写的库,用于在Java对象和JSON数据之间进行映射。这个库使得Java对象可以轻松地序列化成JSON格式,同时也可以从JSON字符串反序列化回Java对象。在Java开发中,Gson库非常常见,特别...

    gson jar包下载

    Gson,全称为Google Simple JSON,是Google提供的一款开源...无论是简单的数据交换还是复杂的对象模型,Gson都能提供有效的解决方案。在实际开发中,了解并熟练掌握Gson的使用技巧,无疑会提高工作效率,简化数据操作。

    Google gson

    此外,如果你的数据结构包含循环引用,Gson也提供了解决方案,通过设置`GsonBuilder`的`enableComplexMapKeySerialization`选项。 在实际使用中,Gson库性能优秀,且代码简洁,易于集成到任何Java项目中。不过,...

    com.google.gson.Gson 2.8.0 jar包

    截止至2016-12-23,github上com.google.gson.Gson 最新的2.8.0jar包。强大的json字符串解析功能及将字符串转换为json格式。才发现需要这么多分,大家也可以去网盘下载: ...

    com.google.gson.Gson 2.8.1 2.8.2 jar包 gson

    Gson是Google开发的一款强大的Java库,用于在Java对象和JSON数据之间进行映射。它的全称是Google Gson,主要用于将Java对象转换为JSON格式的字符串,也可以将JSON字符串反序列化为对应的Java对象。在Java开发中,...

    Google-Gson 2.2.4

    1. 在处理循环引用时,Gson可能会导致栈溢出错误,需要特殊处理。 2. Gson默认不处理日期,需要自定义类型适配器进行日期的序列化和反序列化。 3. 默认情况下,Gson会忽略非公开(private)的字段,如果需要序列化...

    gson-2.6.2.zip

    标题中的"gson-2.6.2.zip"指的是Gson库的版本2.6.2的压缩包文件,包含了Gson库的核心组件——gson-2.6.2.jar。 Gson的核心功能主要体现在以下几个方面: 1. JSON序列化:Gson能够将Java对象转换为对应的JSON字符串...

    gson-2.6.2.jar包(com.google.code.gson:gson:2.6.2)

    这样做是因为Google的官方仓库可能由于网络问题或地域限制无法直接访问,此时手动下载并添加库文件成为了必要的解决方案。一旦将jar包放入`libs`目录,开发者需要在项目构建配置中引入该库,使其成为项目的一部分。 ...

    google-gson-2.2.4.zip

    首先,我们来了解一下JSON(JavaScript Object Notation)——这是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON格式与JavaScript语法非常相似,但JSON是一种独立于语言的数据交换...

    gson需要的jar包

    gson需要的四个jar包,gson-2.0、log4j-1.2.17、slf4j-api-1.7.10、slf4j-log4j12-1.7.10。导入这四个jar包后import com.google.gson.Gson;就不会报错了。

    gson2.8.0和2.8.6.rar

    如果你需要对Gson进行深度定制或者解决特定问题,源码将提供极大的帮助。 使用Gson时,你可以通过以下步骤将其引入Java项目: 1. 将对应的JAR文件添加到项目的类路径中,这通常可以通过IDE(如IntelliJ IDEA或...

    json解析 gson fastjson

    使用Gson,你可以通过`Gson().toJson()`方法将Java对象转化为JSON字符串,通过`new Gson().fromJson()`方法将JSON字符串反序列化为Java对象。 例如: ```java Person person = new Person("John", "Doe"); String ...

    gson-2.8.5版本的jar包

    GSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。 Gson是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个JSON字符串...

    com.google.gson.Gson.jar

    json我们在网络请求中经常用到,最近最火的微信小程序开发中更是必不可少。... 用户列表对象,使用JSONObject jsonStu = JSONObject.fromObject(list);...资源中提供了jar包与代码示例,一句代码解决您的问题。

    gson—2.3.jar

    标题提到的"gson—2.3.jar"指的是Gson库的特定版本——2.3。 在描述中提到了两个jar包,一个是"gson-2.3-sources.jar",另一个是"gson-2.3.jar"。这两个文件在Java开发中各有其用途: 1. **gson-2.3.jar**:这是...

    Google发布的强大的gson包

    谷歌的Gson库是一款高效的Java库,用于在Java对象和JSON...无论是简单的数据转换,还是复杂的对象序列化,Gson都能提供简单而灵活的解决方案。如果你在Java项目中需要与JSON数据打交道,Gson无疑是一个值得考虑的选择。

    googleGson JsonObject json转换包

    包含以下java源文件: com.google.gson.DefaultDateTypeAdapter.class com.google.gson.ExclusionStrategy.class com.google.gson.FieldAttributes.class com.google.gson.FieldNamingPolicy.class ...

Global site tag (gtag.js) - Google Analytics