`
yxb1990
  • 浏览: 69624 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Jackson 动态过滤属性

阅读更多

用到的类库为:Jackson 版本1.9.5, 最近在看Google guava,所以用上了,版本是12.0-rc1

废话不多说,定义两个Bean 

这两个bean 是父子关系。

public class User {
	private String name;
	private Date createDate;
	private Set<Article> articles = Sets.newHashSet();

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Date getCreateDate() {
		return createDate;
	}
	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}
	public Set<Article> getArticles() {
		return articles;
	}
	public void setArticles(Set<Article> articles) {
		this.articles = articles;
	}
}
public class Article {
	private String title;
	private User user;

	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
}

然后自己写的一个Jackson实用类

public class Jacksons {
	private ObjectMapper objectMapper;

	public static Jacksons me() {
		return new Jacksons();
	}

	private Jacksons() {
		objectMapper = new ObjectMapper();
		// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
		objectMapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);
		objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

		objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
	}

	public Jacksons filter(String filterName, String... properties) {
		FilterProvider filterProvider = new SimpleFilterProvider().addFilter(filterName,
				SimpleBeanPropertyFilter.serializeAllExcept(properties));
		objectMapper.setFilters(filterProvider);
		return this;
	}

	public Jacksons addMixInAnnotations(Class<?> target, Class<?> mixinSource) {
		objectMapper.getSerializationConfig().addMixInAnnotations(target, mixinSource);
		objectMapper.getDeserializationConfig().addMixInAnnotations(target, mixinSource);
		return this;
	}

	public Jacksons setDateFormate(DateFormat dateFormat) {
		objectMapper.setDateFormat(dateFormat);
		return this;
	}

	public <T> T json2Obj(String json, Class<T> clazz) {
		try {
			return objectMapper.readValue(json, clazz);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("解析json错误");
		}
	}

	public String readAsString(Object obj) {
		try {
			return objectMapper.writeValueAsString(obj);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("解析对象错误");
		}
	}

	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> json2List(String json) {
		try {
			return objectMapper.readValue(json, List.class);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("解析json错误");
		}
	}
}

最后是测试:

public class Test {
	public static void main(String args[]) {
		User user = new User();
		user.setName("chris");
		user.setCreateDate(new Date());
		Article article = new Article();
		article.setTitle("title");
		article.setUser(user);
		Set<Article> articles = Sets.newHashSet(article);
		user.setArticles(articles);
		
		String userJson = Jacksons.me().readAsString(user);
		String articleJson = Jacksons.me().readAsString(article);
		System.out.println(userJson);
		System.out.println(articleJson);
	}
}

1.父子关系引用

直接输出肯定是报循环错误,Jackson 提供了两个注解

@JsonManagedReference

public Set<Article> getArticles() {

return articles;

}

@JsonBackReference

public User getUser() {

return user;

}

打印结果为:{"name":"chris","createDate":"2012-04-18","articles":[{"title":"title"}]}, {"title":"title"}

2.@JsonIgnore注解

只说父子引用关系的。父子两边都加@JsonIgnore打印字符串为:

{"name":"chris","createDate":"2012-04-18"},{"title":"title"}

单向User加该注解 

@JsonIgnore

public Set<Article> getArticles() {

return articles;

}

打印结果为:

{"name":"chris","createDate":"2012-04-18"}

{"title":"title","user":{"name":"chris","createDate":"2012-04-18"}}

单向Article 加该注解

@JsonIgnore

public User getUser() {

return user;

}

打印结果:

{"name":"chris","createDate":"2012-04-18","articles":[{"title":"title"}]}

{"title":"title"}

3.@JsonIgnoreType(没用过)

4.@JsonIgnoreProperties

这个加在类级别上用法很简单@JsonIgnoreProperties({"property1", "property2"})

动态过滤属性,这个比较麻烦。

有两种方法。

1.使用@JsonFilter注解

 

使用方法为先给ObjectMapper添加一个filter,然后还要在需要过滤的类上加@JsonFilter("filterName")注解。

比如说要过滤User 上的name属性,先

 

Jacksons.me().filter("myFilter""name").readAsString(user),具体看Jacksons代码。并在User类上加@JsonFilter("myFilter")。

有点不爽的是如果用另外一个没有添加该filter的ObjectMapper解析的话会报错。

 

如果这个User类已经添加了@JsonFilter("myFilter")注解,但在另外一个地方又要解析它并不想过滤name 属性,那只能是

Jacksons.me().filter("myFilter"""),然后在读出来。

2.添加混入注解(暂时这么翻译)

 

定义一个接口或类先在该类上添加@JsonIgnoreProperties("name"), 然后在ObjectMapper的配置项上添加混入注解

输出为:

 

String mixInUser = Jacksons.me().addMixInAnnotations(User.class, MixInUser.class).readAsString(user);

System.out.println(mixInUser);

有兴趣的童鞋可以看下例子。

写的有点乱,没排好版。大家凑和这看吧。

分享到:
评论
2 楼 qiaokou 2019-04-07  
Jacksons.me().filter("myFilter", "name").readAsString(user),具体看Jacksons代码。并在User类上加@JsonFilter("myFilter")。
有点不爽的是如果用另外一个没有添加该filter的ObjectMapper解析的话会报错。
SimpleFilterProvider.setFailOnUnknownId(false)
1 楼 jyan1992 2013-11-22  
请问下啊。。。如果不用这个注解。。。怎么过滤属性呢?

相关推荐

    jackson工具类有动态属性过虑功能

    jackson工具类有动态属性过虑功能.在业务应用中经常会有指定属性序列化json的需求,

    jackson-dynamic-filter-spring-boot-starter:使用Jackson轻松动态确定过滤器的简便方法

    Jackson动态属性过滤器-Spring Boot Starter 用于Spring Boot Starter,它提供了一种简便的方法,可以通过动态确定过滤,而无需直接在Java对象上编写注释,并且还可以与Spring MVC / Spring Boot很好地集成。 先决...

    jackson-dynamic-filter:一种使用Jackson来动态确定过滤器的简便方法

    杰克逊动态属性过滤器基本上,当您使用Gson时,需要从目标对象上的序列化WITHOUT批注中排除特定字段,您将使用ExclusionStrategy 。 但是我在杰克逊没有找到类似的方法来做到这一点。 因此,此存储库提供了一种动态...

    springMVC4-rest-jackson-jsonview-annotation.zip

    我们的POJO使用@JsonView注解属性传递已经定义的视图。在Spring的Controller我们可以使用Jackson的@JsonView注解我们的方法。序列化Http响应体的时候,JSON响应将在配置视图的基础上进行过滤。我们也可以在Spring ...

    jackson-jaxrs-propertyfiltering

    杰克逊·贾克斯(Jackson-Jaxrs)属性过滤 概述 用于启用自动过滤来自JAX-RS端点的JSON响应的库。 客户端通过查询参数指定他们想要的属性,并且库负责将响应实体过滤为仅这些属性(请参见的示例)。 经过Jersey测试...

    spring-mvc-JsonIgnoreDynamically:渲染前按名称从 jackson json 序列化中排除某些字段

    spring-mvc-Json动态忽略目的 : 有时,过滤序列化到 HTTP 响应主体的上下文对象会很有用。在某些情况下,返回的部分数据可能对使用 API 的设备没有用,或者应该对公众保持不可见,因此不应该t 通过 JSON 序列化和...

    Spring Boot中文文档.rar

    27.1.Jackson 27.2.GSON 27.3.JSON-B 28.开发Web应用程序 28.1.“Spring Web MVC框架” 28.1.1.Spring MVC自动配置 28.1.2.HttpMessageConverters 28.1.3.自定义JSON序列化程序和反序列化程序 ...

    spring security 参考手册中文版

    10.4Jackson 支持 96 第三部分 测试 97 11.测试方法安全性 97 11.1安全测试设置 98 11.2 @WithMockUser 98 11.3 @WithAnonymousUser 100 11.4 @用户详细信息 101 11.5 @WithSecurityContext 102 11.6测试元注释 104 ...

    JAVA上百实例源码以及开源项目

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    JAVA上百实例源码以及开源项目源代码

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

Global site tag (gtag.js) - Google Analytics