大家好,又见面了,我是全栈君。
场景:有时候我们做系统的时候,比如两个请求,返回同一个对象,但是需要的返回字段并不相同。
常见与写前端接口的时候,尤其是手机端,一般需要什么数据就返回什么样的数据。此时对于返回同一个对象我们就要动态过滤所需要的字段…
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
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108594.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...