重写 FastJson 属性过滤器

Posted on 2013-09-16 22:36 H2O 阅读(2816) 评论(0)  编辑  收藏 所属分类: java

Fastjson介绍

简介

Fastjson是一个Java语言编写的高性能功能完善的JSON库。由阿里巴巴

高性能

fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson。并且还超越了google的二进制协议protocol buf。

支持标准
  • Fastjson完全支持http://json.org的标准,也是官方网站收录的参考实现之一。

功能强大
  • 支持各种JDK类型。包括基本类型、JavaBean、Collection、Map、Enum、泛型等。

  • 支持循环引用

无依赖
  • 不需要例外额外的jar,能够直接跑在JDK上。

支持范围广
  • 支持JDK 5、JDK 6、Android、阿里云手机等环境。

开源
测试充分
  • fastjson有超过1500个testcase,每次构建都会跑一遍,丰富的测试场景保证了功能稳定。

下载

http://code.alibabatech.com/mvn/releases/com/alibaba/fastjson/


详细:fastjson 项目介绍


背景:刚接触这个开源项目不久。遇到问题也不少。不过通过各方询问、及源码探究开源得到解决。最近使用FastJson结合hibernate做项目,发现关于对象的级联属性的过滤上用的不是很顺。当然简单的属性过滤 @温少 已经提供了 SimplePropertyPreFilter 使用,使用方法有详细说明的。这里我针对级联属性的过滤对该类做了补充。(当然你也可以使用注解实现)

ok、上代码:


package com.example.util.fastjson;
   
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
   
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.suncompass.example.auth.entity.AuthEmployee;
import com.suncompass.example.auth.entity.AuthMenu;
import com.suncompass.framework.base.entity.BaseEntity;
   
/**
 * 
@author :晨风²º¹³ <br>
 * @Comment : fastjson 针对类型的属性选择过滤器(可以跨层级) <br>
 
*/
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(),用来判断对象是否是类的实例
           
        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(BaseEntity.
class.isInstance(new AuthEmployee()));
        System.out.println(AuthEmployee.
class.isInstance(new AuthMenu()));
           
        System.out.println(BaseEntity.
class.isAssignableFrom(AuthEmployee.class));
    }
}
测试代码:
package com.example.auth.test.fastjson;
   
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
   
import com.alibaba.fastjson.JSON;
import com.example.util.fastjson.ComplexPropertyPreFilter;
   
public class A {
       
    
private Integer aid;
       
    
private B b;
       
    
private List<C> c = new ArrayList<>();
       
    
public A() {
        
super();
    }
       
    
public static void main(String[] args) {
        A a 
= new A();
        a.setAid(
1);
           
        B b 
= new B();
        b.setBid(
2);
           
        a.setB(b);
        b.setA(a);
           
        C c 
= new C();
        c.setId(
3);
           
        a.getC().add(c);
        b.getC().add(c);
        c.setA(a);
        c.setB(b);
           
        ComplexPropertyPreFilter filter 
= new ComplexPropertyPreFilter();
           
        filter.setExcludes(
new HashMap<Class<?>, String[]>() {
               
            
private static final long serialVersionUID = -8411128674046835592L;
               
            {
                put(A.
classnew String[] { "aid" });
                put(B.
classnew String[] { "bid""a" });
                put(C.
classnew String[] { "a""b" });
            }
        });
               
        System.out.println(JSON.toJSONString(a, filter));
           
    }
       
    
public Integer getAid() {
        
return aid;
    }
       
    
public void setAid(Integer aid) {
        
this.aid = aid;
    }  
public B getB() {
        
return b;
    }
       
    
public void setB(B b) {
        
this.b = b;
    }
       
    
public List<C> getC() {
        
return c;
    }
       
    
public void setC(List<C> c) {
        
this.c = c;
    }
       
}
package com.example.auth.test.fastjson;
   
import java.util.ArrayList;
import java.util.List;
   
public class B {
       
    
private Integer bid;
       
    
private A a;
       
    
private List<C> c = new ArrayList<>();
       
    
public B() {
        
super();
    }
       
    
public Integer getBid() {
        
return bid;
    }
       
    
public void setBid(Integer bid) {
        
this.bid = bid;
    }
       
    
public A getA() {
        
return a;
    }
       
    
public void setA(A a) {
        
this.a = a;
    }
       
    
public List<C> getC() {
        
return c;
    }
       
    
public void setC(List<C> c) {
        
this.c = c;
    }
       
}
package com.example.auth.test.fastjson;
   
public class C {
       
    
private Integer id;
       
    
private A a;
       
    
private B b;
       
    
public C() {
        
super();
    }
       
    
public A getA() {
        
return a;
    }
       
    
public void setA(A a) {
        
this.a = a;
    }
       
    
public B getB() {
        
return b;
    }
       
    
public void setB(B b) {
        
this.b = b;
    }
       
    
public Integer getId() {
        
return id;
    }
       
    
public void setId(Integer id) {
        
this.id = id;
    }
       
}
ok,代码已贴好,测试方法在A类。
From :
http://aijava.duapp.com/archives/override-fastjson-propertyprefilter.html


只有注册用户登录后才能发表评论。


网站导航:
 

posts - 0, comments - 21, trackbacks - 0, articles - 101

Copyright © H2O