java中如何使用注解实现对某个dto对象实现是否为空的判断校验实例,dto对象里面包括list数据,单个字段,单条dto数据,为空提示某某字段不能为空,自定义注解可以添加多个字段,包括字段名称,提示

java Copy code
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.List;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface NotEmpty {
    String fieldName() default "";
    String message() default "";
}

class FieldEmptyException extends RuntimeException {
    public FieldEmptyException(String message) {
        super(message);
    }
}

class Validator {
    public static void validate(Object obj) throws IllegalAccessException {
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(NotEmpty.class)) {
                field.setAccessible(true);
                Object fieldValue = field.get(obj);
                if (fieldValue == null || isEmptyList(fieldValue)) {
                    NotEmpty annotation = field.getAnnotation(NotEmpty.class);
                    String fieldName = annotation.fieldName();
                    String message = annotation.message();
                    if (message.isEmpty()) {
                        message = fieldName + " cannot be null.";
                    }
                    throw new FieldEmptyException(message);
                } else if (fieldValue instanceof List) {
                    List listValue = (List) fieldValue;
                    if (listValue.isEmpty()) {
                        NotEmpty annotation = field.getAnnotation(NotEmpty.class);
                        String fieldName = annotation.fieldName();
                        String message = annotation.message();
                        if (message.isEmpty()) {
                            message = "The list in " + fieldName + " cannot be empty.";
                        }
                        throw new FieldEmptyException(message);
                    } else {
                        for (Object item : listValue) {
                            validate(item); // 递归遍历列表中的元素进行校验
                        }
                    }
                } else {
                    validate(fieldValue); // 递归处理其他类型的字段对象进行校验
                }
            }
        }
    }

    private static boolean isEmptyList(Object obj) {
        return obj instanceof List && ((List) obj).isEmpty();
    }
}

class UserDTO {
    @NotEmpty(fieldName = "Username", message = "Please provide a valid username.")
    private String username;

    @NotEmpty(fieldName = "Email")
    private String email;

    @NotEmpty(fieldName = "Roles")
    private List roles;

    @NotEmpty(fieldName = "Address")
    private AddressDTO address;

    // 省略其他字段和构造方法

    // getter和setter方法
}

class AddressDTO {
    @NotEmpty(fieldName = "Street")
    private String street;

    @NotEmpty(fieldName = "City")
    private String city;

    // 省略其他字段和构造方法

    // getter和setter方法
}

public class Main {
    public static void main(String[] args) {
        UserDTO user1 = new UserDTO();
        user1.setUsername("John");
        user1.setEmail("");
        user1.setRoles(List.of());
        user1.setAddress(new AddressDTO());

        try {
            validateUser(user1);
            System.out.println("User 1 is valid.");
        } catch (FieldEmptyException e) {
            System.out.println("Validation failed: " + e.getMessage());
        }

        UserDTO user2 = new UserDTO();
        user2.setUsername("Alice");
        user2.setEmail("[email protected]");
        user2.setRoles(List.of("admin"));
        AddressDTO address = new AddressDTO();
        address.setStreet("");
        user2.setAddress(address);

        try {
            validateUser(user2);
            System.out.println("User 2 is valid.");
        } catch (FieldEmptyException e) {
            System.out.println("Validation failed: " + e.getMessage());
        }
    }

    public static void validateUser(@Validate UserDTO user) {
        try {
            Validator.validate(user);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
在上面的代码示例中,我们使用了自定义注解 @NotEmpty 来标记需要进行非空校验的字段,在 Validator 类中实现了验证逻辑。UserDTO 和 AddressDTO 类分别表示用户和地址的数据传输对象,包含需要进行验证的字段,并通过 getter 和 setter 方法暴露给外部调用。

在 Main 类中,我们创建了两个用户对象 user1 和 user2 作为测试数据,并使用 validateUser() 方法来触发对象的非空校验,根据结果输出相应的信息。

请注意,代码示例中最后的 validateUser() 方法使用了 @Validate 注解,这是一种自定义的注解,用于标记需要进行验证

上面的@Validate注解方法怎么实现呢
在前面的代码示例中,我使用了 @Validate 注解来标记需要进行验证的方法。这是一个自定义的注解,可以通过反射机制来获取并执行相应的验证逻辑。以下是添加 @Validate 注解的方式:

创建自定义注解 @Validate,用于标记需要进行验证的方法。
java
Copy code
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Validate {
}
修改 UserDTO 类,在需要进行验证的方法上添加 @Validate 注解。
java
Copy code
class UserDTO {
    private String username;
    private String email;
    private List roles;
    private AddressDTO address;

    // 省略其他字段和构造方法

    @Validate
    public void validate() {
        // 执行验证逻辑
        Validator.validate(this);
    }

    // getter和setter方法
}
在 Main 类中修改 validateUser() 方法,用于调用带有 @Validate 注解的验证方法。
java
Copy code
public class Main {
    public static void main(String[] args) {
        UserDTO user1 = new UserDTO();
        user1.setUsername("John");
        user1.setEmail("");
        user1.setRoles(List.of());
        user1.setAddress(new AddressDTO());

        try {
            user1.validate();
            System.out.println("User 1 is valid.");
        } catch (FieldEmptyException e) {
            System.out.println("Validation failed: " + e.getMessage());
        }

        UserDTO user2 = new UserDTO();
        user2.setUsername("Alice");
        user2.setEmail("[email protected]");
        user2.setRoles(List.of("admin"));
        AddressDTO address = new AddressDTO();
        address.setStreet("");
        user2.setAddress(address);

        try {
            user2.validate();
            System.out.println("User 2 is valid.");
        } catch (FieldEmptyException e) {
            System.out.println("Validation failed: " + e.getMessage());
        }
    }
}
在上述的代码示例中,将 validate() 方法添加到 UserDTO 类中,并在方法上添加了 @Validate 注解。然后,在 Main 类中调用 user1.validate() 和 user2.validate() 来触发对象的验证逻辑。

这样,当调用带有 @Validate 注解的验证方法时,会执行 Validator.validate(this),其中 this 表示当前对象,即 UserDTO 对象。通过这种方式,可以在对象级别实现验证逻辑,并在需要验证的地方进行调用。

你可能感兴趣的:(springboot,java,java)