锁定老帖子 主题:Jackson 动态过滤属性
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-04-18
用到的类库为: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); 有兴趣的童鞋可以看下例子。 写的有点乱,没排好版。大家凑和这看吧。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-04-20
昨天因为json解析的循环调用问题,搞了1下午
你说你,早点发啊... |
|
返回顶楼 | |
发表时间:2012-04-20
定义两个Bean 先
这两个bean 是父子关系。 楼主确定是父子关系? |
|
返回顶楼 | |
发表时间:2012-04-20
应该是吧,被你这种语气说的我都不确定了,要不换个说法,就一对多和多对一。
|
|
返回顶楼 | |
发表时间:2012-04-20
WAMING5 写道 定义两个Bean 先
这两个bean 是父子关系。 楼主确定是父子关系? 哈哈,有点问毛了 |
|
返回顶楼 | |
发表时间:2012-04-20
一对多的循环问题确实很烦人,如果在springmvc中responsebody怎么处理这种关系?
|
|
返回顶楼 | |
发表时间:2012-04-25
单例ObjectMapper 加上
Jacksons.me().addMixInAnnotations(User.class, MixInUser.class).readAsString(user); 会有线程安全问题隐患的 |
|
返回顶楼 | |
发表时间:2012-04-25
abc-127 写道 单例ObjectMapper 加上
Jacksons.me().addMixInAnnotations(User.class, MixInUser.class).readAsString(user); 会有线程安全问题隐患的 我这个应该不算是单例吧,me()方法每次都是new 一个ObjectMapper出来的,objectMapper不是共享的。 |
|
返回顶楼 | |
发表时间:2012-04-26
yxb1990 写道 abc-127 写道 单例ObjectMapper 加上
Jacksons.me().addMixInAnnotations(User.class, MixInUser.class).readAsString(user); 会有线程安全问题隐患的 我这个应该不算是单例吧,me()方法每次都是new 一个ObjectMapper出来的,objectMapper不是共享的。 没看清楚 ,不过 这样一来,性能下降了很多 new ObjectMapper()出来的性能和sef-josn差不多 有时更慢 |
|
返回顶楼 | |
浏览 14432 次