栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java函数式接口-非空字段校验

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java函数式接口-非空字段校验

一、概述

做一个,可以传入对象,方法声明的形式校验参数非空,想要实现的效果如下

  //user类:Long id,String name;
   User user = new User(1L,"");
   JsonUtils.validEmpty(user,User::getId,User::getName);

说一下思路

  • 传入对象,方法声明(即对象方法),可以用到有来有回的函数接口 R apply(T t)。

  • 函数接口可以获取的信息有:

    1. 传入的类型
    2. 传入的调用方法
    3. 对象对应方法的返回值
    4. 对象对应方法返回值类型
  • 校验到非空字段后,需要知道这个字段代表什么意思,这里使用一个自定义注解,将此注解到对应字段上,里面的value就是字段含义

  • 逻辑:

    1. 根据传入的对象user,获取到对象对应方法的值(apply函数接口特性)
    2. 根据获取的值做非空校验,获取到为空的字段
    3. 获取字段Field类信息(知道 Class对象,调用方法)
    4. 获取字段的注解value
    5. 返回为空的字段信息。
二、自定义函数接口
import com.cuihq.testdemo.annotation.CommentTarget;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Optional;

//函数式接口注解
@FunctionalInterface
public interface SFunction extends Serializable {
   
   R apply(T t);


   
   default SerializedLambda getSerializedLambda() throws Exception {
      //writeReplace改了好像会报异常
      Method write = this.getClass().getDeclaredMethod("writeReplace");
      write.setAccessible(true);
      return (SerializedLambda) write.invoke(this);
   }

   
   default String getImplClass() {
      try {
         //这里拿到的数据是com/cuihq/。。。 
         //需要将 /转换成. 利用Class.forName才会生效
         String implClass = getSerializedLambda().getImplClass();
         String result = implClass.replace("/", ".");
         return result;
      } catch (Exception e) {
         return null;
      }
   }

   
   default String getImplMethodName() {
      try {
         return getSerializedLambda().getImplMethodName();
      } catch (Exception e) {
         return null;
      }
   }

   
   default String getFieldName(){
      String methodName = this.getImplMethodName();
      String valueTmp = StringUtils
                          .removeStartIgnoreCase(methodName, "get");
      String valuePre = valueTmp.substring(0, 1);
      String valueSux = valueTmp.substring(1);
      return valuePre.toLowerCase() + valueSux;
   }

   
   default  String getCommentValue(){
      String fieldName = this.getFieldName();
      String implClass = this.getImplClass();
      Field f = null;
      try {
         f = getField(Class.forName(implClass), fieldName);
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      }
      CommentTarget commentTarget = null;
      if(f!=null){
         commentTarget = f.getAnnotation(CommentTarget.class);
      }
      return commentTarget==null ? "": commentTarget.value();
   }

   
   default Field getField( Class c, String FieldName) {
      try {
         Field f = c.getDeclaredField(FieldName);
         return f;
      } catch (NoSuchFieldException e) {
         if (c.getSuperclass() == null){
            return null;
         }
         else{
            return getField( c.getSuperclass(), FieldName);
         }
      } catch (Exception ex) {
         return null;
      }
   }
}
二、自定义注解
package com.cuihq.testdemo.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;



@Retention(RetentionPolicy.RUNTIME)
public @interface CommentTarget {
   
   String value() default "";
}
三、工具类方法
static  void validEmpty(Object obj, SFunction... functions){
   String msg = Stream.of(functions)
         .filter(x -> isAnyoneEmpty(x.apply((T) obj)))
         .map(fun -> String.format("【%s】不能为空", fun.getCommentValue()))
         .collect(Collectors.joining(","));
   System.out.println(msg);
}

private static boolean isAnyoneEmpty(Object obj) {
   if (obj == null) {
      return obj == null;
   } else if (obj instanceof Collection) {
      return ((Collection) obj).isEmpty();
   } else if (obj instanceof String) {
      return obj.toString().length() == 0;
   } else if (obj.getClass().isArray()) {
      return ((Object[]) obj).length == 0;
   } else if (obj instanceof Map) {
      return ((Map) obj).isEmpty();
   } else if (obj instanceof StringBuffer) {
      return ((StringBuffer) obj).length() == 0;
   } else if (obj instanceof StringBuilder) {
      return ((StringBuilder) obj).length() == 0;
   }
   return false;
}
四、单元测试
@Test
public void validEmptyTest() {
   User user = new User(1L,"");
   JsonUtils.validEmpty(user,User::getId,User::getName);
}

输出结果

【自定义name】不能为空
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/332566.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号