Spring Boot RESTful API 动态过滤嵌套对象字段:AOP 和 反射实现

本文将介绍两种方法在 Spring Boot 中实现 RESTful API 动态过滤嵌套对象字段,即使字段值为 null,只要请求参数包含该字段,就返回该字段。两种方法分别是使用 AOP 和 反射实现。

1. 使用 AOP 实现动态过滤

首先定义一个注解 @DynamicFilter,用于标记需要进行动态过滤的方法:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DynamicFilter {
    String[] value() default {};
}

然后定义一个切面类 DynamicFilterAspect,用于在方法执行前进行动态过滤:

@Aspect
@Component
public class DynamicFilterAspect {

    @Autowired
    private ObjectMapper objectMapper;

    @Around("@annotation(com.example.demo.annotation.DynamicFilter)")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 获取需要过滤的字段
        String[] fields = request.getParameterValues("fields");

        // 执行被标记的方法
        Object result = joinPoint.proceed();
        if (fields != null && fields.length > 0) {
            // 进行动态过滤
            String json = objectMapper.writeValueAsString(result);
            JsonNode rootNode = objectMapper.readTree(json);
            for (String field : fields) {
                String[] fieldsArray = field.split("\.");
                JsonNode node = rootNode;
                for (String subField : fieldsArray) {
                    node = node.get(subField);
                    if (node == null) {
                        break;
                    }
                }
                if (node != null) {
                    ((ObjectNode) node).removeAll();
                }
            }
            result = objectMapper.readValue(rootNode.toString(), result.getClass());
        }
        return result;
    }
}

最后在需要动态过滤的方法上加上 @DynamicFilter 注解:

@GetMapping("/users/{id}")
@DynamicFilter({"address.city", "address.country"})
public User getUserById(@PathVariable Long id) {
    return userService.getUserById(id);
}

2. 使用反射实现动态过滤

定义一个工具类 DynamicFilterUtil,用于进行动态过滤:

public class DynamicFilterUtil {

    public static <T> T dynamicFilter(T object, String[] fields) throws Exception {
        if (fields != null && fields.length > 0) {
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(object);
            JsonNode rootNode = objectMapper.readTree(json);
            for (String field : fields) {
                String[] fieldsArray = field.split("\.");
                JsonNode node = rootNode;
                for (String subField : fieldsArray) {
                    node = node.get(subField);
                    if (node == null) {
                        break;
                    }
                }
                if (node != null) {
                    ((ObjectNode) node).removeAll();
                }
            }
            object = objectMapper.readValue(rootNode.toString(), (Class<T>) object.getClass());
        }
        return object;
    }

}

在需要动态过滤的地方调用该工具类:

@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id, @RequestParam(required = false) String[] fields) throws Exception {
    User user = userService.getUserById(id);
    return DynamicFilterUtil.dynamicFilter(user, fields);
}

3. 请求案例

请求 URL:http://localhost:8080/users/1?fields=name,address.city

请求参数:fields=name,address.city

返回结果:

{
    "id": 1,
    "name": "Alice",
    "address": {
        "city": "New York",
        "state": "NY"
    }
}

总结

本文介绍了两种在 Spring Boot 中实现 RESTful API 动态过滤嵌套对象字段的方法,分别使用 AOP 和 反射。两种方法都能实现动态过滤,但各有优劣:

  • AOP 更加面向切面编程,代码结构更清晰,但需要定义注解和切面,代码量稍微多一些。
  • 反射更加灵活,可以根据需要动态调用方法,但代码结构相对复杂,需要处理反射异常。

开发者可以根据自己的实际情况选择合适的方法实现 RESTful API 动态过滤功能。


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

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