spring boot 自定义注解过滤返回字段

                   启动类

package com.fuhang.mall;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@MapperScan("com.fuhang.mall.mapper")
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class MallPlatformApplication {

    public static void main(String[] args) {
        SpringApplication.run(MallPlatformApplication.class, args);
    }

}

ApplicationConfig类如下:

package com.fuhang.mall.config;
 
import java.util.List;

import com.fuhang.mall.handler.JsonReturnHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class ApplicationConfig implements WebMvcConfigurer {// 生效
	@Bean
	public JsonReturnHandler jsonReturnHandler() {
		return new JsonReturnHandler();// 初始化json过滤器
	}
 
	@Override
	public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
		returnValueHandlers.add(jsonReturnHandler());
 
	}
}

JsonReturnHandler类如下:

package com.fuhang.mall.handler;
import com.fuhang.mall.annotation.JsonFieldFilter;
import com.fuhang.mall.config.JsonFilterSerializer;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletResponse;


public class JsonReturnHandler implements HandlerMethodReturnValueHandler {
	@Override
	public void handleReturnValue(Object returnObject, MethodParameter paramter, ModelAndViewContainer container, NativeWebRequest request) throws Exception {
		container.setRequestHandled(true);
		JsonFilterSerializer serializer = new JsonFilterSerializer();
		if (paramter.hasMethodAnnotation(JsonFieldFilter.class)) {// 如果有JsonFieldFilter注解,则过滤返回的对象returnObject
			JsonFieldFilter jsonFilter = paramter.getMethodAnnotation(JsonFieldFilter.class);
			serializer.filter(jsonFilter.type() == null ? returnObject.getClass() : jsonFilter.type(), jsonFilter.include(), jsonFilter.exclude());// 调用过滤方法
		}
		HttpServletResponse response = request.getNativeResponse(HttpServletResponse.class);
		assert response != null;
		response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
		response.getWriter().write(serializer.toJson(returnObject));
	}
 
	@Override
	public boolean supportsReturnType(MethodParameter methodParameter) {
		return methodParameter.hasMethodAnnotation(JsonFieldFilter.class);
	}
}

JsonFilterSerializer类如下: 注意如果你的实体类用了继承 也就是base类的话则需要二次过滤

使用clazz.getSuperclass() 获取到父类即可

package com.fuhang.mall.config;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

public class JsonFilterSerializer {
	private static final String DYNC_INCLUDE = "DYNC_INCLUDE";// 包含的标识
	private static final String DYNC_EXCLUDE = "DYNC_EXCLUDE";// 过滤的标识
	private ObjectMapper mapper = new ObjectMapper();
 
	@JsonFilter(DYNC_EXCLUDE)
	interface DynamicExclude {
	}
 
	@JsonFilter(DYNC_INCLUDE)
	interface DynamicInclude {
	}
 
	public void filter(Class<?> clazz, String include, String exclude) {
		if (clazz == null)
			return;
		if (include != null && include.length() > 0) {
			// 包含的操作
			mapper.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_INCLUDE, SimpleBeanPropertyFilter.filterOutAllExcept(include.split(","))));
			// 多个字段用,分割开
			mapper.addMixIn(clazz, DynamicInclude.class);
			if (clazz.getSuperclass()!=null){
				mapper.addMixIn(clazz.getSuperclass(), DynamicInclude.class);
			}
		} else if (exclude != null && exclude.length() > 0) {
			mapper.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_EXCLUDE, SimpleBeanPropertyFilter.serializeAllExcept(exclude.split(","))));
			mapper.addMixIn(clazz, DynamicExclude.class);
			if (clazz.getSuperclass()!=null){
				mapper.addMixIn(clazz.getSuperclass(), DynamicInclude.class);
			}
		}
	}
	public String toJson(Object object) throws JsonProcessingException {
		return mapper.writeValueAsString(object);
	}
}

自定义注解 JsonFieldFilter如下:

package com.fuhang.mall.annotation;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * @ClassName ${NAME}.java
 * @author 神秘的凯
 * @version 1.0.0
 * @Description JSON 过滤自定义注解
 * @createTime 2022/4/3 11:06 上午
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonFieldFilter {
	Class<?> type();// 对哪个类的属性进行过滤
 
	String include() default "";// 包含哪些字段,即哪些字段可以显示
 
	String exclude() default "";// 不包含哪些字段,即哪些字段不可以显示
}

过滤的实体类如下

package com.fuhang.mall.entity;
import com.fuhang.mall.BaseEntity;
import com.fuhang.mall.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

/**
 * 实体类
 *
 * @author 小白
 * @since 2022-04-02
 */
@Data
@TableName("fh_city")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "City对象", description = "City对象")
public class City extends BaseEntity {

	private static final long serialVersionUID = 1L;

	@TableId(value = "code", type = IdType.AUTO)
	private String code;
	@TableField("name")
	private String name;
	@TableField("province_code")
	private String provinceCode;


}

 最后测试controller如下:

 注意点:

 1、用@Controller 替代 @RestController;

 2、在不需要过滤字段 的接口上面使用@ResponseBody注解 不然会报错 找不到视图装配器

 3,   但是在需要 过滤字段的接口上一定不要用@ResponseBody注解,否则过滤失效。因为配置了过滤器会自动被解析JSON 不用加@ResponseBody

/*
 * Copyright 2020-2030, MateCloud, DAOTIANDI Technology Inc All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * Author: pangu([email protected])
 */
package com.fuhang.mall.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.fuhang.mall.BaseEntity;
import com.fuhang.mall.BaseSearch;
import com.fuhang.mall.annotation.JsonFieldFilter;
import com.fuhang.mall.api.Result;
import com.fuhang.mall.entity.Area;
import com.fuhang.mall.response.ResponseModel;
import com.fuhang.mall.service.IAreaService;
import com.fuhang.mall.vo.CityVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import lombok.AllArgsConstructor;

import com.fuhang.mall.annotation.Logs;

import org.springframework.web.bind.annotation.RestController;
import com.fuhang.mall.BaseController;
import com.fuhang.mall.service.ICityService;
import com.fuhang.mall.entity.City;
import javax.validation.Valid;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 小白
 * @since 2022-04-02
 */
@Controller
@AllArgsConstructor
@Api(tags = "省市区")
public class CityAPI extends BaseController {
    @Autowired
    private  ICityService cityService;
    @Autowired
    private IAreaService areaService;

    /**
     * 获取城市列表
     *
     * @param search  搜索关键词
     * @return Result
     */
    @Logs(value = "城市列表", exception = "城市列表请求异常")
    @GetMapping("/searchCityList")
    @ApiOperation(value = "获取城市列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "keyword", value = "模糊查询关键词", paramType = "form"),
    })
    @JsonFieldFilter(type = City.class, exclude = "createBy,updateBy,createTime,updateTime")
    public ResponseModel<CityVO> searchCityList(BaseSearch search) {
       return cityService.searchCityList(search);
    }


    /**
     * 获取城市列表
     *
     * @param code  获取区县城市列表
     * @return Result
     */
    @Logs(value = "获取区县列表", exception = "获取区县列表请求异常")
    @GetMapping("/searchAreaList")
    @ApiOperation(value = "获取区县列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", required = true, value = "城市编码", paramType = "form"),
    })
    @JsonFieldFilter(type = City.class, exclude = "createBy,updateBy,createTime,updateTime")
    public ResponseModel<List<Area>> searchAreaList(String code) {
        return areaService.searchAreaList(code);
    }
}

猜你喜欢

转载自blog.csdn.net/fujiakai/article/details/123934379