实现过程:

  1. 创建一个注解@DynamicFilter,用于标识需要进行动态过滤的方法或类。
  2. 使用AOP拦截被@DynamicFilter注解标识的方法或类,获取请求参数中的过滤字段,并使用反射对对象进行过滤,返回过滤后的结果。
  3. 对于嵌套对象,使用递归的方式进行过滤。

代码实现:

  1. 创建注解@DynamicFilter
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface DynamicFilter {
}
  1. 使用AOP拦截被@DynamicFilter注解标识的方法或类,并进行动态过滤
@Component
@Aspect
public class DynamicFilterAspect {

    @Autowired
    private HttpServletRequest request;

    @Around("@annotation(com.example.demo.annotation.DynamicFilter) || @within(com.example.demo.annotation.DynamicFilter)")
    public Object dynamicFilter(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();

        // 获取请求参数中的过滤字段
        String fields = request.getParameter("fields");
        if (StringUtils.isBlank(fields)) {
            return result;
        }

        // 对结果进行过滤
        String[] fieldArray = fields.split(",");
        List<String> fieldList = Arrays.asList(fieldArray);
        if (fieldList.size() > 0) {
            if (result instanceof List) {
                List<Object> resultList = new ArrayList<>();
                for (Object obj : (List) result) {
                    Object filtered = filterObject(obj, fieldList);
                    resultList.add(filtered);
                }
                return resultList;
            } else {
                return filterObject(result, fieldList);
            }
        }
        return result;
    }

    private Object filterObject(Object obj, List<String> fieldList) {
        try {
            // 使用反射获取对象的所有属性
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldName = field.getName();

                // 如果属性是对象,则对其进行递归过滤
                if (field.getType().getClassLoader() != null) {
                    Object nestedObj = field.get(obj);
                    if (nestedObj != null) {
                        Object filteredNestedObj = filterObject(nestedObj, fieldList);
                        field.set(obj, filteredNestedObj);
                    }
                } else {
                    // 对属性进行过滤
                    if (!fieldList.contains(fieldName)) {
                        field.set(obj, null);
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return obj;
    }
}
  1. 在Controller中使用@DynamicFilter注解标识需要进行动态过滤的方法
@RestController
@RequestMapping("/users")
@DynamicFilter
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }

    @GetMapping
    public List<User> getUsers() {
        return userService.getUsers();
    }
}
  1. 发送请求

请求案例:

获取用户列表,只返回id和name字段

GET http://localhost:8080/users?fields=id,name

返回结果:

[
    {
        "id": 1,
        "name": "Alice"
    },
    {
        "id": 2,
        "name": "Bob"
    }
]

获取用户详情,返回id、name和address字段,同时address只返回province和city字段

GET http://localhost:8080/users/1?fields=id,name,address.province,address.city

返回结果:

{
    "id": 1,
    "name": "Alice",
    "address": {
        "province": "Beijing",
        "city": "Haidian"
    }
}

原文地址: https://www.cveoy.top/t/topic/bgH9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录