Jackson 动态过滤属性,编程式过滤对象中的属性
场景:有时候我们做系统的时候,比如两个请求,返回同一个对象,但是需要的返回字段并不相同。
常见与写前端接口的时候,尤其是手机端,一般需要什么数据就返回什么样的数据。此时对于返回同一个对象我们就要动态过滤所需要的字段...
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 动态过滤属性,编程式过滤对象中的属性的更多相关文章
- spring data mongodb中,如果对象中的属性不想加入到数据库字段中
spring data mongodb中,如果对象中的属性不想加入到数据库字段中,可加@Transient注解,声明为透明属性 spring data mongodb 官网帮助文档 http://ww ...
- JavaScript 深入了解对象中的属性
本篇主要介绍JS中对象的属性,包括:属性的分类.访问方式.检测属性.遍历属性以及属性特性等内容. 目录 1. 介绍:描述属性的命名方式.查找路径以及分类 2. 属性的访问方式:介绍'.'访问方式.'[ ...
- java工具类之按对象中某属性排序
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang ...
- 在Map对象中获取属性,注意判断为空
在Map对象中获取属性,注意判断为空 public static void main(String[] args) { Map map = new HashMap(); Integer i = (In ...
- 遍历js对象中的属性
可以使用js自带的for in.也可以使用Ext JS中的方法来遍历js对象中的属性 代码如下: /** 遍历对象 */ var person = {name:'张泰松',age:28}; //js方 ...
- JS基础_枚举对象中的属性
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 枚举对象中的属性 for . . in
枚举对象中的属性:把对象中所有的属性和值都取出来 使用 for . . . in 语句 语法: for(var 变量 in 对象){ } for . . . in 语句 对象中有几个属性,循 ...
- 微信小程序:给data中对象中的属性设置值与给data中的属性或对象或数组设置值的区别
一.给data中的属性或对象或数组设置值,属性名不需要加引号 this.setData({ material: param, // 这里material为对象 } this.setData({ d ...
- C#验证对象中的属性是否为空的共通方法
在后台接口处理时,经常需要对请求的参数做验证.因此提取了共通方法,方便进行判断. /// <summary> /// 数据验证工具类 /// </summary> public ...
随机推荐
- linux应用之openssh server安装及配置(centos)
安装OpenSSH Server 首先,我们搜索一下CentOS的软件库里面有没有已经定义好的SSH服务器包: $ yum search ssh ... ... openssh.x86_64 : An ...
- Tensorflow深度学习之十二:基础图像处理之二
Tensorflow深度学习之十二:基础图像处理之二 from:https://blog.csdn.net/davincil/article/details/76598474 首先放出原始图像: ...
- js获取dom对象style样式的值
js获取到的dom对象的style通常是没有值得,因为我们都写在外部文件中,从慕课网上见到讲师封装的一个方法,挺不错.特此记录下来. function getStyle(obj,attr){ if(o ...
- 深度学习网络结构中超参数momentum了解
训练网络时,通常先对网络的初始权值按照某种分布进行初始化,如:高斯分布.初始化权值操作对最终网络的性能影响比较大,合适的网络初始权值能够使得损失函数在训练过程中的收敛速度更快,从而获得更好的优化结果. ...
- bzoj 1086 [SCOI2005]王室联邦——思路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1086 于是去看了题解. 要回溯的时候再把自己加进栈里判断.这样才能保证剩下的可以通过自己连到 ...
- UVA562(01背包均分问题)
Dividing coins Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Descriptio ...
- 是否要从单片机转为嵌入式Linux?
作者:嵌入式老鸟火哥 授权转载于公众号嵌入式老鸟的职场之道(ID: ict_embedded),有增加内容和修改. 最近很多童鞋投票并咨询如何从单片机转为嵌入式Linux开发.看来读者圈中做单片机,R ...
- Linux--top命令查看系统状态,所有值讲解
Linux系统可以通过top命令查看系统的CPU.内存.运行时间.交换分区.执行的线程等信息.通过top命令可以有效的发现系统的缺陷出在哪里.是内存不够.CPU处理能力不够.IO读写过高. 一.top ...
- 三、Chrome开发者工具详解(3)-Timeline面板
摘自: http://www.cnblogs.com/charliechu/p/5992177.html
- Linux Ctrl+Z的使用方法
假设你发现前台运行的一个程序需要很长的时间,但是需要干其他的事情,你就可以用 Ctrl-Z ,终止这个程序,然后可以看到系统提示: [1]+ Stopped /root/bin/rsync.sh 然后 ...