Что нужно знать об отражении — отражение для реализации проверки сущностей

Java задняя часть API регулярное выражение

В процессе разработки необходимо проверять входящие параметры, особенно объекты, чтобы убедиться, что входящие параметры имеют правильный формат. Вот очень простой компонент для проверки. Пусть каждый глубоко задумается о применении рефлексии.

нужно

Для ежедневной разработки внешние и внутренние системы связаны через API.Проверка параметров API – это функция с очень высокой частотой использования.Если проверку параметров можно выполнить очень легко, объем кода может сократиться, а эффективность работы может быть повышена.

использовать

адрес проекта:GitHub.com/IT Рисовая лапша/Meifu…

Ранее использовался самый примитивный метод проверки:

 if(testEntity.getImages().length()>2){
            //这里是业务逻辑
        }
        if(testEntity.getTitle().length()>2){
            //这里是业务逻辑
        }

Это приводит к тому, что для реализации требуется слишком много повторяющегося кода, а разработка занимает слишком много времени. Здесь метод аннотаций используется для оптимизации, необходимо только определить содержание проверки, когда сущность определена, и метод, который нужно вызвать только для проверки, может использоваться, когда он используется.

/**
     * 定义测试的实体
     */

    public class TestEntity{
        /**
         * 图片
         */
        @Valid(description = "图片",minLength = 1,maxLength = 200,regex=".*runoob.*")
        private String images;

        /**
         * 标题
         */
        @Valid(description = "标题",isEmpty = false,maxLength = 20)
        private String title;


        public String getImages() {
            return images;
        }

        public void setImages(String images) {
            this.images = images;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }
поле иллюстрировать
description Китайское имя поля
isEmpty Это обнуляемый
maxLength Максимальная длина
minLength Минимальная длина
regex регулярное выражение

При проверке вам нужно только позвонить объекту для проверки

ValidResultEntity validResultEntity = EntityCheckUtil.validate(testEntity);
System.out.println(validResultEntity.getMessage());

Возвращенный объект ValidResultEntity сообщит вам, был ли он успешным, и если это была ошибка, он сообщит вам причину ошибки.

Описание исходного кода

На самом деле общая идея реализации очень проста, в основном используются пользовательские аннотации Java для проверки.
Определите новую аннотацию (Valid.java):


@Documented
@Inherited
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Valid {


    /**
     * @return 字段描述
     */
    public String description() default "";

    /**
     * 是否可以为空
     * @return true可以为空,false不能为空
     */
    public boolean isEmpty() default true;

    /**
     * 最大长度
     * @return
     */
    public int maxLength() default 1000;

    /**
     * 最小长度
     * @return
     */
    public int minLength() default 0;

    /**
     * 正则表达式
     * @return
     */
    public  String regex() default "";

}

Создайте общий метод для выполнения проверки:

     /**
     * 注解验证电泳方法
     *
     * @param bean 验证的实体
     * @return
     */

    public static ValidResultEntity validate(Object bean) {
        ValidResultEntity result = new ValidResultEntity();
        result.setSucceed(true);
        result.setMessage("验证通过");

        Class<?> cls = bean.getClass();

        // 检测field是否存在
        try {
            // 获取实体字段集合
            Field[] fields = cls.getDeclaredFields();
            for (Field f : fields) {
                // 通过反射获取该属性对应的值
                f.setAccessible(true);
                // 获取字段值
                Object value = f.get(bean);
                // 获取字段上的注解集合
                Annotation[] arrayAno = f.getAnnotations();
                for (Annotation annotation : arrayAno) {
                    // 获取注解类型(注解类的Class)
                    Class<?> clazz = annotation.annotationType();
                    // 获取注解类中的方法集合
                    Method[] methodArray = clazz.getDeclaredMethods();
                    for (Method method : methodArray) {
                        // 获取方法名
                        String methodName = method.getName();

                        if("description".equals(methodName)) {
                            continue;
                        }


                        // 初始化注解验证的方法处理类 (我的处理方法写在本类中)
                        Object obj = EntityCheckUtil.class.newInstance();
                        // 获取方法
                        try {
                            // 根据方法名获取该方法
                            Method m = obj.getClass().getDeclaredMethod(methodName, Object.class, Field.class);
                            // 调用该方法
                            result = (ValidResultEntity) m.invoke(obj, value, f);
                            /* 验证结果 有一处失败则退出 */
                            if(result.isSucceed()==false) {
                                return result;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

validate в основном получает значение и аннотацию класса через рефлексию и вызывает его по полученным данным:

// 根据方法名获取该方法
Method m = obj.getClass().getDeclaredMethod(methodName, Object.class, Field.class);
// 调用该方法
result = (ValidResultEntity) m.invoke(obj, value, f);
/* 验证结果 有一处失败则退出 */
if(result.isSucceed()==false) {
   return result;
}

В Invoke полученный метод реализуется конкретным вызовом, здесь я определяю самые простые методы, в том числе:

  • isEmpty
  • maxLength
  • minLength
  • regex

На самом деле, вы можете сами расширять больше методов, пока вы понимаете эту идею, вы можете сами настраивать больше правил.

Расширение идей

Будь то java или .net, все они поддерживают отражение.Применение отражения на самом деле очень широкое, и код легко абстрагировать.После того, как конкретная разработка будет успешной, ее действительно можно хорошо расширить. На самом деле, существует множество зрелых продуктов для фреймворков проверки сущностей (таких как:hibernate.org/validator/)…
Приведенный выше код очень прост, но он может сэкономить много работы.Еще раз, вы можете подумать о многих подобных реализациях, таких как:

  • На основе аннотаций кеша
@redis(key='test',expire=1800)
    public void  testOldRedis(){
        if(testEntity.getImages().length()>2){
            //这里是业务逻辑
        }
        if(testEntity.getTitle().length()>2){
            //这里是业务逻辑
        }
    }
  • На основе аннотаций MQ

Конечно, это все нужно разрабатывать самому.На самом деле ответственность за разработку не высока, но это может сделать структуру кода более понятной и лаконичной.Отражение точно не черная технология, а ядерное оружие что повышает эффективность.

(Заканчивать)


Приглашаю всех обратить внимание на мой публичный аккаунт, чтобы общаться, учиться и получать последние статьи как можно скорее.
Идентификатор WeChat: itmifen