在hibernate 中比 SimplePropertyPreFilter 还要好用的过滤类
比官方自带的过滤类(SimplePropertyPreFilter )还好用,那肯定是自定义的啦!
先讲下结果吧,看是不是诸位要的:
- 能过滤类中的属性类,无论是Set集合,List集合,还是EJB都能过滤
- 能解决多对多,或者是一对多,一对一等关系映射死循环,数据返回数据多,杂,乱等特点
- 做json的主宰,想要返回的数据是哪些字段就返回哪些字段
- 简单上手
好吧上代码:
package intercepter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import model.wudun.Articles;
import model.wudun.Comment;
import model.wudun.Member;
import java.util.*;
/**
* @Author:wj
* @Date:Created in 15:16 2018/1/5
* @Description:用 fasjson 对 hibernate 级联关系进行过滤
*/
public class ComplexPropertyPreFilter implements PropertyPreFilter {
private Map<Class<?>, String[]> includes = new HashMap<>();
private Map<Class<?>, String[]> excludes = new HashMap<>();
static {
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
}
public ComplexPropertyPreFilter() {
}
public ComplexPropertyPreFilter(Map<Class<?>, String[]> includes) {
super();
this.includes = includes;
}
public boolean apply(JSONSerializer serializer, Object source, String name) {
//对象为空。直接放行
if (source == null) {
return true;
}
// 获取当前需要序列化的对象的类对象
Class<?> clazz = source.getClass();
// 无需序列的对象、寻找需要过滤的对象,可以提高查找层级
// 找到不需要的序列化的类型
for (Map.Entry<Class<?>, String[]> item : this.excludes.entrySet()) {
// isAssignableFrom(),用来判断类型间是否有继承关系
if (item.getKey().isAssignableFrom(clazz)) {
String[] strs = item.getValue();
// 该类型下 此 name 值无需序列化
if (isHave(strs, name)) {
return false;
}
}
}
// 需要序列的对象集合为空 表示 全部需要序列化
if (this.includes.isEmpty()) {
return true;
}
// 需要序列的对象
// 找到不需要的序列化的类型
for (Map.Entry<Class<?>, String[]> item : this.includes.entrySet()) {
// isAssignableFrom(),用来判断类型间是否有继承关系
if (item.getKey().isAssignableFrom(clazz)) {
String[] strs = item.getValue();
// 该类型下 此 name 值无需序列化
if (isHave(strs, name)) {
return true;
}
}
}
return false;
}
/*
* 此方法有两个参数,第一个是要查找的字符串数组,第二个是要查找的字符或字符串
*/
public static boolean isHave(String[] strs, String s) {
for (int i = 0; i < strs.length; i++) {
// 循环查找字符串数组中的每个字符串中是否包含所有查找的内容
if (strs[i].equals(s)) {
// 查找到了就返回真,不在继续查询
return true;
}
}
// 没找到返回false
return false;
}
public Map<Class<?>, String[]> getIncludes() {
return includes;
}
public void setIncludes(Map<Class<?>, String[]> includes) {
this.includes = includes;
}
public Map<Class<?>, String[]> getExcludes() {
return excludes;
}
public void setExcludes(Map<Class<?>, String[]> excludes) {
this.excludes = excludes;
}
public static void main(String[] args) {
// use instanceOf,用来判断对象是否是类的实例
// use isAssignableFrom(),用来判断类型间是否有继承关系
// use isInstance(),用来判断对象是否是类的实例
//setExcludes(),进行过滤的类!!!!
Class<?> intClass = Integer.class;
// Create various objects.
String str = "Hello";
Date date = new Date();
Integer i = new Integer(10);
// Is str an instance of class Integer?
boolean check1 = intClass.isInstance(str);
System.out.println("str is an Integer? " + check1);
// Is date an instance of class Integer?
boolean check2 = intClass.isInstance(date);
System.out.println("date is an Integer? " + check2);
// Is i an instance of class Integer?
boolean check3 = intClass.isInstance(i);
System.out.println("i is an Integer? " + check3);
System.out.println(Articles.class.isInstance(new Comment()));
System.out.println(Comment.class.isInstance(new Articles()));
System.out.println(Articles.class.isAssignableFrom(Member.class));
//这里是测试代码!! 博主一些EJB类 不要纠结导不出来!!!! 不要纠结导不出来!!!! 不要纠结导不出来!!!!
List<Articles> articlesList = new ArrayList<>(0);
Articles articles = new Articles();
articles.setId("articles_1");
Comment comment = new Comment();
comment.setCommentId("comment_1");
Member member = new Member();
member.setId("member_1");
articles.setMember(member);
Set<Articles> articlesSet = new LinkedHashSet<>(0);
articlesSet.add(articles);
member.setArticlesCollect(articlesSet);
Set<Member> memberSet = new LinkedHashSet<>(0);
memberSet.add(member);
articles.setMemberSet(memberSet);
Set<Comment> commentSet = new LinkedHashSet<>(0);
commentSet.add(comment);
articles.setComments(commentSet);
member.setCommentSet(commentSet);
comment.setMember(member);
articlesList.add(articles);
ComplexPropertyPreFilter filter = new ComplexPropertyPreFilter();
filter.setExcludes(new HashMap<Class<?>, String[]>() {
private static final long serialVersionUID = -8411128674046835592L;//我也不知道这是干嘛的 删除或者不写不会影响其功能和效果
{ //对象 Articles中 : 多对多属性:giveRewardSet(Set集合) memberSet(Set集合)
put(Articles.class, new String[] { "giveRewardSet","memberSet"});//放入过滤的对象,然后是需要过滤的对象里的属性
//对象Comment :commentId(Comment对象中普通的属性), member(Comment对象中对象属性)
put(Comment.class, new String[] { "commentId", "member" });
//对象Member :nickname(Member对象中普通的属性) 多对多属性: articlesCollect(Set集合)
put(Member.class, new String[] { "nickname", "articlesCollect" });
//当然 多对一 一对一也是可以过滤的啦!!! 如果还有不清楚的欢迎询问
}
});
System.out.println(JSON.toJSONString(articlesList, filter));
}
}
谢谢!若有问题欢迎踩…
由于被博主遇到这个问题深感头疼 然后机缘巧合的状况下刷到博客,觉得该博主博客不是很详细没有很好的说明这个实体类的强大性能,然后博主觉得这篇博客埋没于码海中是在可以故此转发 , 脱茂!!:
https://www.cnblogs.com/sandyfog/articles/3679804.html
向老前辈致敬