前后台传参数时,忽略和要修改的属性字段

第一,先定义一个过滤器:

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:

前后台传参数时,忽略和要修改的属性字段