场景:有时候我们做系统的时候,比如两个请求,返回同一个对象,但是需要的返回字段并不相同。
常见与写前端接口的时候,尤其是手机端,一般需要什么数据就返回什么样的数据。此时对于返回同一个对象我们就要动态过滤所需要的字段...
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
转载于:https://www.cnblogs.com/huzi007/p/6626990.html
相关资源:JAVA上百实例源码以及开源项目