前后台传参数时,忽略和要修改的属性字段
第一,先定义一个过滤器:
package com.miot.filter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jeecgframework.core.util.ResourceUtil;
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.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
public class JacksonJsonFilter extends FilterProvider {
// 只返回某些字段Map
Map<Class<?>, Set<String>> includeMap = new HashMap<>();
// 过滤掉某些字段Map
Map<Class<?>, Set<String>> filterMap = new HashMap<>();
// 在某些字段返回时添加绝对路径
Map<Class<?>, Set<String>> baseUrlMap = new HashMap<>();
// 只返回某些字段
public void include(Class<?> type, String[] fields) {
addToMap(includeMap, type, fields);
}
// 过滤掉某些字段
public void filter(Class<?> type, String[] fields) {
addToMap(filterMap, type, fields);
}
// 添加某些字段的绝对路径(注意这里的方法名必须和JSON中的方法名一样)
public void baseUrl(Class<?> type, String[] fields) {
addBaseUrlToMap(baseUrlMap, type, fields);
}
private void addToMap(Map<Class<?>, Set<String>> map, Class<?> type, String[] fields) {
Set<String> fieldSet = map.get(type);
if (null == fieldSet || !map.containsValue(fieldSet)) {
fieldSet = new HashSet<>();
}
fieldSet.addAll(Arrays.asList(fields));
map.put(type, fieldSet);
}
private void addBaseUrlToMap(Map<Class<?>, Set<String>> map, Class<?> type, String[] fields) {
String address = ResourceUtil.getConfigByName("address");
Set<String> fieldSet = map.get(type);
if (null == fieldSet || !map.containsValue(fieldSet)) {
fieldSet = new HashSet<>();
}
List<String> list = Arrays.asList(fields);
List<String> fieldsList = new ArrayList<String>();
for (String field : list) {
field = address + field;
fieldsList.add(field);
}
fieldSet.addAll(fieldsList);
map.put(type, fieldSet);
}
@Override
public BeanPropertyFilter findFilter(Object arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public com.fasterxml.jackson.databind.ser.PropertyFilter findPropertyFilter(Object fieldId, Object valueToFilter) {
return new SimpleBeanPropertyFilter() {
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider prov,
BeanPropertyWriter writer) throws Exception {
if (apply(pojo.getClass(), writer.getName())) {
writer.serializeAsField(pojo, jgen, prov);
} else if (jgen.canOmitFields()) {
writer.serializeAsField(pojo, jgen, prov);
}
}
};
}
public boolean apply(Class<?> type, String name) {
String address = ResourceUtil.getConfigByName("address");
Set<String> includeFields = includeMap.get(type);
Set<String> filterFields = filterMap.get(type);
Set<String> baseUrlFields = baseUrlMap.get(type);
// 如果过滤字段不是null,并且传过来的那个参数在includefields的Set集合里面则返回true,则把name里的所有字段全部返回,其余的不返回
if (includeFields != null && includeFields.contains(name)) {
return true;
// 如果过滤的filterFields不是null并且filterFields的set集合中不包含name属性返回true,如果判断之后为true,则把name全给过滤掉,不传给前端,
} else if (filterFields != null && !filterFields.contains(name)) {
return true;
// 如果baseUrlFileds不是null,并且传过来的那个参数在baseUrlFieds的Set集合里面则返回true,则把name里的所有字段全部返回,其余的不返回,
} else if (baseUrlFields != null && baseUrlFields.contains(address + name)) {
return true;
} else if (includeFields == null && filterFields == null && baseUrlFields == null) {
return true;
}
return false;
}
}
第二,定义注解:
package com.miot.filter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(JSONS.class) // 让方法支持多重@JSON 注解
public @interface JSON {
Class<?> tpye();
String include() default "";
String filter() default "";
String baseUrl() default "";
}
第三、定义一个注解数组:
package com.miot.filter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JSONS {
JSON[] value();
}
第四、定义一个json返回的控制器
package com.miot.filter;
import java.util.ArrayList;
import java.util.List;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import com.miot.base.filtIngoreDemo.CustomerJsonSerializer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class JsonReturnHandler implements HandlerMethodReturnValueHandler {
List<ResponseBodyAdvice<Object>> advices = new ArrayList<>();
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception {
mavContainer.setRequestHandled(true);
for (int i = 0; i < advices.size(); i++) {
ResponseBodyAdvice<Object> ad = advices.get(i);
if (ad.supports(returnType, null)) {
returnValue = ad.beforeBodyWrite(returnValue, returnType, MediaType.APPLICATION_JSON_UTF8, null,
new ServletServerHttpRequest(webRequest.getNativeRequest(HttpServletRequest.class)),
new ServletServerHttpResponse(webRequest.getNativeResponse(HttpServletResponse.class)));
}
}
}
@Override
public boolean supportsReturnType(MethodParameter returnType) {
boolean hasJSONAnno = returnType.getMethodAnnotation(JSON.class) != null
|| returnType.getMethodAnnotation(JSONS.class) != null;
return hasJSONAnno;
}
}
demo: