场景:有时候我们做系统的时候,比如两个请求,返回同一个对象,但是需要的返回字段并不相同。

常见与写前端接口的时候,尤其是手机端,一般需要什么数据就返回什么样的数据。此时对于返回同一个对象我们就要动态过滤所需要的字段...

Spring MVC 默认使用转json框架是 jackson。 大家也知道, jackson 可以在实体类内加注解,来指定序列化规则,但是那样比较不灵活,不能实现我们目前想要达到的这种情况

下面用编程式的方式实现过滤字段.

先写个json工具类:

public class JsonUtilJackson {

    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final ObjectMapper mapper; JacksonJsonFilter jacksonFilter = new JacksonJsonFilter(); static {
SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
mapper = new ObjectMapper();
mapper.setDateFormat(dateFormat);
// 允许对象忽略json中不存在的属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 允许出现特殊字符和转义符
mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
// 允许出现单引号
mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
// 忽视为空的属性
mapper.setSerializationInclusion(Include.NON_EMPTY);
} public static JsonUtilJackson me() {
JsonUtilJackson jsonUtil = new JsonUtilJackson();
return jsonUtil;
} public void filter(Class<?> clazz, String include, String filter) {
if (clazz == null)
return;
if (StringUtils.isNotBlank(include)) {
jacksonFilter.include(clazz, include.split(","));
}
if (StringUtils.isNotBlank(filter)) {
jacksonFilter.filter(clazz, filter.split(","));
}
mapper.addMixIn(clazz, jacksonFilter.getClass());
} public String toJson(Object obj) {
try {
mapper.setFilterProvider(jacksonFilter);
return mapper.writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException("转换json字符失败!");
}
} public <T> T toObject(String json, Class<T> clazz) {
try {
return mapper.readValue(json, clazz);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("将json字符转换为对象时失败!");
}
} public <T> T toObject(String json, TypeReference<T> clazz) {
try {
return mapper.readValue(json, clazz);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("将json字符转换为对象时失败!"); }
} }

然后写个JsonFilter

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set; import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; @SuppressWarnings("deprecation")
@JsonFilter("JacksonFilter")
public class JacksonJsonFilter extends FilterProvider{ Map<Class<?>, Set<String>> includeMap = new HashMap<>();
Map<Class<?>, Set<String>> filterMap = new HashMap<>(); public void include(Class<?> type, String[] fields) {
addToMap(includeMap, type, fields);
} public void filter(Class<?> type, String[] fields) {
addToMap(filterMap, type, fields);
} private void addToMap(Map<Class<?>, Set<String>> map, Class<?> type, String[] fields) {
Set<String> filedSet=new HashSet<>();
if(fields!=null && fields.length>0){
for(String filed : fields){
filedSet.add(filed);
}
}
map.put(type, filedSet);
} @Override
public BeanPropertyFilter findFilter(Object filterId) {
throw new UnsupportedOperationException("Access to deprecated filters not supported");
} @Override
public PropertyFilter findPropertyFilter(Object filterId, Object valueToFilter) { return new SimpleBeanPropertyFilter() { @Override
public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider prov, PropertyWriter writer)
throws Exception {
if (apply(pojo.getClass(), writer.getName())) {
writer.serializeAsField(pojo, jgen, prov);
} else if (!jgen.canOmitFields()) {
writer.serializeAsOmittedField(pojo, jgen, prov);
}
}
};
} public boolean apply(Class<?> type, String name) {
Set<String> includeFields = includeMap.get(type);
Set<String> filterFields = filterMap.get(type);
if (includeFields != null && includeFields.contains(name)) {
return true;
} else if (filterFields != null && !filterFields.contains(name)) {
return true;
} else if (includeFields == null && filterFields == null) {
return true;
}
return false;
} }

最后就是我们测试了

    public static void main(String[] args) throws Exception {

        A a=new A();
a.setName("AAAAA");
a.setNo("011111"); Role r=new Role();
r.setName("zhangsan");
r.setCode("11");
r.setCreateTime(new Date().getTime());
r.setRemark("who am i"); a.setR(r); JsonUtilJackson jtk= new JsonUtilJackson();
// 设置转换 Article 类时,只包含 id, name
jtk.filter(A.class, "no,r", null);
jtk.filter(Role.class, "name,remark", null);
String ss=jtk.toJson(a);
System.out.println(ss); }

结果:{"no":"011111","r":{"name":"zhangsan","remark":"who am i"}}

参考:https://my.oschina.net/diamondfsd/blog/836727?p=3&temp=1490578919756#blog-comments-list

Jackson 动态过滤属性,编程式过滤对象中的属性的更多相关文章

  1. spring data mongodb中,如果对象中的属性不想加入到数据库字段中

    spring data mongodb中,如果对象中的属性不想加入到数据库字段中,可加@Transient注解,声明为透明属性 spring data mongodb 官网帮助文档 http://ww ...

  2. JavaScript 深入了解对象中的属性

    本篇主要介绍JS中对象的属性,包括:属性的分类.访问方式.检测属性.遍历属性以及属性特性等内容. 目录 1. 介绍:描述属性的命名方式.查找路径以及分类 2. 属性的访问方式:介绍'.'访问方式.'[ ...

  3. java工具类之按对象中某属性排序

    import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang ...

  4. 在Map对象中获取属性,注意判断为空

    在Map对象中获取属性,注意判断为空 public static void main(String[] args) { Map map = new HashMap(); Integer i = (In ...

  5. 遍历js对象中的属性

    可以使用js自带的for in.也可以使用Ext JS中的方法来遍历js对象中的属性 代码如下: /** 遍历对象 */ var person = {name:'张泰松',age:28}; //js方 ...

  6. JS基础_枚举对象中的属性

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 枚举对象中的属性 for . . in

    枚举对象中的属性:把对象中所有的属性和值都取出来 使用 for . . . in 语句 语法: for(var  变量  in  对象){ } for  . . . in 语句  对象中有几个属性,循 ...

  8. 微信小程序:给data中对象中的属性设置值与给data中的属性或对象或数组设置值的区别

    一.给data中的属性或对象或数组设置值,属性名不需要加引号 this.setData({ material: param, // 这里material为对象 } this.setData({   d ...

  9. C#验证对象中的属性是否为空的共通方法

    在后台接口处理时,经常需要对请求的参数做验证.因此提取了共通方法,方便进行判断. /// <summary> /// 数据验证工具类 /// </summary> public ...

随机推荐

  1. 数据库之Oracle

    数据库之Oracle 一. 用户的管理 1. 用户就是好比公司的某个人,而权限是这个人能在公司做什么,他的角色就是说明他的职位. 2. 用户的权限分为: 系统权限:对别的用户的管理操作. 对象权限:对 ...

  2. 在KitKat(Android 4.4.2) 推送网址给手机

    弱者才会回避问题. 最近想把网址推送给手机实现后台下载,打算故技重施,用短信传送然后中断广播的方法实现隐蔽传送.试了半天发现怎么现在拦不住短信了.查了一下才发现原来Android4.4增加了一个安全机 ...

  3. Hihocoder 1625 : 重复字符串匹配 (KMP)

    描述 给定两个字符串A和B,请你求出字符串A最少重复几次才能使得B是A的子串. 例如A="hiho",B="hohihohi".则A重复3次之后变为" ...

  4. hibernate 中的拦截器EmptyInterceptor接口功能

    Interceptor接口提供了从会话(session)回调(callback)应用程序(application)的机制, 这种回调机制可以允许应用程序在持久化对象被保存.更新.删除或是加载之前,检查 ...

  5. smokeping部署安装

    smokeping部署安装 部署情况: 服务器IP:192.168.10.18 smokeping部署在/var/www/html/smokeping目录 smokeping部分命令: smokepi ...

  6. 设计模式学习笔记 1.factory 模式

    Factory 模式 用户不关心工厂的具体类型,只知道这是一个工厂就行. 通过工厂的实现推迟到子类里面去来确定工厂的具体类型. 工厂的具体类型来确定生产的具体产品. 同时用户不关心这是一个什么样子的产 ...

  7. mongodb "$"的作用

    { "_id": ObjectId("58e48e32830f398e8f401a95"), "_class": "com.ydd ...

  8. 第一篇:构建第一个SpringBoot工程

    简介 spring boot 它的设计目的就是为例简化开发,开启了各种自动装配,你不想写各种配置文件,引入相关的依赖就能迅速搭建起一个web工程.它采用的是建立生产就绪的应用程序观点,优先于配置的惯例 ...

  9. Qt生成CSV 文件

    1.CSV 文件 不支持 EXCEL中 的多个工作表的模式. 一个 CVS 文件只能转换成 EXCEL 一个工作表. 2.逗号分隔值(Comma-Separated Values,CSV,有时也称为字 ...

  10. 我叫mt3.0更新公告

    1.增加卡牌: (1)炮姐,种族:牛头人,职业:元素萨满,可在任务中使用万能碎片兑换,最多兑换5张: (2)娘子,种族:德莱尼人,职业:治疗萨满,进化材料为死亡视察者: 详情点击查看>>& ...