Spring Boot 实现字段唯一校验功能(实例代码)

目录
  • 1 Maven依赖
  • 2 实现代码
    • 2.1 UniqueCheck
    • 2.2 UniqueCheckDetail
    • 2.3 UniqueCheckArgs
    • 2.4 UniqueCheckService
    • 2.5 AbstractUniqueCheckService
  • 3 调试代码
    • 3.1 UserCheckArgs
    • 3.2 UserUniqueCheckVo
    • 3.3 UserUniqueCheckService
    • 3.4 UniqueCheckEnum
    • 3.5 单元测试代码
  • 4 调试结果
  • 注:

1 Maven依赖

<!--   apache 工具包     -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>

2 实现代码

2.1 UniqueCheck

package com.xudongbase.uniquecheck.annotation;

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

/**
 * 在指定的字段用此注解
 * 用来唯一校验
 *
 * @author xudongmaster
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UniqueCheck {
    /**
     * 字段的中文名
     *
     * @return
     */
    String cnName();

    /**
     * 提示
     *
     * @return
     */
    String tip() default "存在重复";
}

2.2 UniqueCheckDetail

package com.xudongbase.uniquecheck;

import lombok.Builder;
import lombok.Data;

/**
 * 唯一校验明细信息
 *
 * @author xudongmaster
 */
@Data
@Builder
public class UniqueCheckDetail {
    /**
     * 字段中文名
     */
   private String fileCnName;
    /**
     * 提示
     */
   private String tip;
}

2.3 UniqueCheckArgs

package com.xudongbase.uniquecheck.args;

/**
 * 唯一校验参数类
 *
 * @author xudongmaster
 */
public interface UniqueCheckArgs {
}

2.4 UniqueCheckService

package com.xudongbase.uniquecheck;
import com.xudongbase.uniquecheck.args.UniqueCheckArgs;

import java.util.List;

/**
 * 唯一校验类
 *
 * @author xudongmaster
 */
public interface UniqueCheckService {
    /**
     * 唯一校验
     *
     * @param args
     * @return
     */
    List<UniqueCheckDetail> uniqueCheck(UniqueCheckArgs args);
}

2.5 AbstractUniqueCheckService

package com.xudongbase.uniquecheck;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.xudongbase.uniquecheck.annotation.UniqueCheck;
import com.xudongbase.uniquecheck.args.UniqueCheckArgs;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 抽象唯一校验类
 *
 * @author xudongmaster
 */
public abstract class AbstractUniqueCheckService<T> implements UniqueCheckService {

    /**
     * 唯一校验
     *
     * @param args
     * @return
     */
    @Override
    public List<UniqueCheckDetail> uniqueCheck(UniqueCheckArgs args) {
        //获取用来校验的数据
        List<T> dataList = getCheckData(args);
        //进行唯一校验
        return implementsUniqueCheck(dataList, args);
    }

    /**
     * 获取用来校验的数据
     *
     * @param args 传参
     * @return
     */
    abstract List<T> getCheckData(UniqueCheckArgs args);

    /**
     * 需要实现的唯一校验
     *
     * @param dataList 用来校验的数据
     * @param args     传参
     * @return
     */
    abstract List<UniqueCheckDetail> implementsUniqueCheck(List<T> dataList, UniqueCheckArgs args);

    /**
     * 通用唯一校验方法
     *
     * @param dataList         用来校验的数据
     * @param needUniqueTarget 需要校验的对象
     * @return
     */
    public static <T> List<UniqueCheckDetail> commonUniqueCheck(List<T> dataList, T needUniqueTarget) {
        List<UniqueCheckDetail> uniqueCheckDetailList = Lists.newLinkedList();
        if (CollUtil.isEmpty(dataList) || needUniqueTarget == null) {
            return uniqueCheckDetailList;
        }
        Class<?> clazz = needUniqueTarget.getClass();
        //获取需要进行唯一校验的字段
        List<Field> fieldList = FieldUtils.getFieldsListWithAnnotation(clazz, UniqueCheck.class);
        if (CollUtil.isEmpty(fieldList)) {
            return uniqueCheckDetailList;
        }
        List<Object> checkFieldValueList;
        Object needUniqueFieldValue;
        Object checkFieldValue;
        UniqueCheckDetail uniqueCheckDetail;
        UniqueCheck uniqueCheck;
        for (Field field : fieldList) {
            field.setAccessible(true);
            checkFieldValueList = Lists.newLinkedList();
            needUniqueFieldValue = null;
            //获取需要校验的字段值
            try {
                needUniqueFieldValue = field.get(needUniqueTarget);
            } catch (Exception e) {
            }
            if (needUniqueFieldValue == null) {
                continue;
            }
            Object filterNeedUniqueFieldValue = needUniqueFieldValue;
            //获取用来校验的对象的字段值
            for (T data : dataList) {
                checkFieldValue = null;
                try {
                    checkFieldValue = field.get(data);
                } catch (Exception e) {
                }
                if (checkFieldValue == null) {
                    continue;
                }
                checkFieldValueList.add(checkFieldValue);
            }
            if (CollUtil.isEmpty(checkFieldValueList)) {
                continue;
            }
            //存在重复的字段值
            if (checkFieldValueList.stream().filter(x -> x.equals(filterNeedUniqueFieldValue)).count() > 0) {
                uniqueCheck = field.getAnnotation(UniqueCheck.class);
                uniqueCheckDetail = UniqueCheckDetail.builder()
                        .fileCnName(uniqueCheck.cnName())
                        .tip(uniqueCheck.cnName() + uniqueCheck.tip()).build();
                uniqueCheckDetailList.add(uniqueCheckDetail);
            }
        }
        return uniqueCheckDetailList;
    }
}

3 调试代码

3.1 UserCheckArgs

package com.xudongbase.uniquecheck.args;

import com.xudongbase.uniquecheck.vo.UserUniqueCheckVo;
import lombok.Data;

/**
 * 用户唯一校验参数类
 *
 * @author xudongmaster
 */
@Data
public class UserCheckArgs implements UniqueCheckArgs {
    /**
     * 需要进行唯一校验的用户信息
     */
    private UserUniqueCheckVo needUniqueTarget;
}

3.2 UserUniqueCheckVo

package com.xudongbase.uniquecheck.vo;

import com.xudongbase.uniquecheck.annotation.UniqueCheck;
import lombok.Data;

/**
 * 用户唯一校验vo
 *
 * @author xudongmaster
 */
@Data
public class UserUniqueCheckVo {
    @UniqueCheck(cnName = "用户id")
    private Long id;

    /**
     * 用户名
     */
    @UniqueCheck(cnName = "用户名")
    private String username;
}

3.3 UserUniqueCheckService

package com.xudongbase.uniquecheck;

import com.google.common.collect.Lists;
import com.xudongbase.uniquecheck.args.UniqueCheckArgs;
import com.xudongbase.uniquecheck.args.UserCheckArgs;
import com.xudongbase.uniquecheck.vo.UserUniqueCheckVo;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 用户唯一校验类
 *
 * @author xudongmaster
 */
@Service("UserUniqueCheckService")
public class UserUniqueCheckService extends AbstractUniqueCheckService<UserUniqueCheckVo> {

    /**
     * 获取用来校验的数据
     *
     * @param args 传参
     * @return
     */
    @Override
    List<UserUniqueCheckVo> getCheckData(UniqueCheckArgs args) {
        List<UserUniqueCheckVo> userUniqueCheckVoList=Lists.newLinkedList();
        UserUniqueCheckVo userUniqueCheckVo=new UserUniqueCheckVo();
        userUniqueCheckVo.setId(1L);
        userUniqueCheckVo.setUsername("xudongmaster");
        userUniqueCheckVoList.add(userUniqueCheckVo);
        return userUniqueCheckVoList;
    }

    /**
     * 需要实现的唯一校验
     *
     * @param dataList 用来校验的数据
     * @param args     传参
     * @return
     */
    @Override
    List<UniqueCheckDetail> implementsUniqueCheck(List dataList, UniqueCheckArgs args) {
        UserCheckArgs userCheckArgs = (UserCheckArgs) args;
        UserUniqueCheckVo needUniqueTarget = userCheckArgs.getNeedUniqueTarget();
        return commonUniqueCheck(dataList, needUniqueTarget);
    }

}

3.4 UniqueCheckEnum

package com.xudongbase.uniquecheck.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * 唯一校验实例枚举类
 *
 * @author Xudongmaster
 */
@Getter
@AllArgsConstructor
public enum UniqueCheckEnum {
    USER("UserUniqueCheckService", "用户唯一校验");
    private final String value;
    private final String name;

}

3.5 单元测试代码

package com.xudongbase.uniquecheck;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.xudongbase.uniquecheck.args.UserCheckArgs;
import com.xudongbase.uniquecheck.enums.UniqueCheckEnum;
import com.xudongbase.uniquecheck.vo.UserUniqueCheckVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;

@SpringBootTest
@Slf4j
public class UniqueCheckTest {
    @Autowired
    private Map<String, UniqueCheckService> uniqueCheckServiceMap;

    /**
     * 测试用户唯一校验
     */
    @Test
    public void testUserUniqueCheck() {
        UserCheckArgs userCheckArgs = new UserCheckArgs();
        UserUniqueCheckVo userUniqueCheckVo = new UserUniqueCheckVo();
        userUniqueCheckVo.setId(2L);
        userUniqueCheckVo.setUsername("xudongmaster");
        userCheckArgs.setNeedUniqueTarget(userUniqueCheckVo);
        List<UniqueCheckDetail> uniqueCheckDetailList = uniqueCheckServiceMap.get(UniqueCheckEnum.USER.getValue()).uniqueCheck(userCheckArgs);
        log.info(JSONObject.toJSONString(uniqueCheckDetailList));
    }

}

4 调试结果

注:

觉得这篇博客写的不错的可以前往Gitee/GitCode点个Star,源码请查看Gitee/GitCode的xudongbase项目unique_check分支。

到此这篇关于Spring Boot 实现字段唯一校验的文章就介绍到这了,更多相关Spring Boot 字段唯一校验内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot通过AOP与注解实现入参校验详情

    目录 前言: 注解标记 通过AOP对方法进行增强 测试Get请求 测试POST请求 解决方法代码 再次测试POST请求 前言: 问题源头: 在日常的开发中,在Service层经常会用到对某一些必填参数进行是否存在的校验.比如我在写一个项目管理系统: 这种必填参数少一些还好,如果多一些的话光是if语句就要写一堆.像我这种有代码洁癖的人看着这一堆无用代码更是难受. 如何解决: 在Spring里面有一个非常好用的东西可以对方法进行增强,那就是AOP.AOP可以对方法进行增强,比如:我要校验参数是否存在

  • SpringBoot进行参数校验的方法详解

    目录 介绍 1.SpringBoot中集成参数校验 1.1引入依赖 1.2定义参数实体类 1.3定义校验类进行测试 1.4打开接口文档模拟提交数据 2.参数异常加入全局异常处理器 3.自定义参数校验 3.1创建自定义注解 3.2自定义校验逻辑 3.3在字段上增加注解 3.4体验效果 4.分组校验 4.1定义分组接口 4.2在模型中给参数分配分组 4.3体现效果 介绍 在日常的接口开发中,为了防止非法参数对业务造成影响,经常需要对接口的参数进行校验,例如登录的时候需要校验用户名和密码是否为空,添加

  • SpringBoot参数校验之@Valid的使用详解

    目录 简介 依赖 代码 测试 测试1:缺少字段 测试2:不缺少字段 测试3:缺少字段,后端获取BindResult 简介 说明 本文用示例说明SpringBoot的@Valid的用法. 依赖 <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> </dependency> 代码 Contr

  • SpringBoot参数校验之@Validated的使用详解

    目录 简介 依赖 用法1:不分组 代码 测试 用法2:分组 代码 测试 简介 说明 本文用示例说明SpringBoot的@Validated的用法. 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> 它里边依赖了hibernat

  • SpringBoot 中使用 Validation 校验参数的方法详解

    目录 1. Validation 介绍 1.1 Validation 注解 1.2 @valid 和 @validated的区别 2. SpringBoot 中使用 Validator 校验参数 2.1 依赖引入 2.2 标注校验实体类 2.3 开启参数校验 2.3.1 简单参数校验 2.3.2 JavaBean 校验 2.4 捕捉参数校验异常 项目中写逻辑时,为保证程序的健壮性,需要对各种参数进行判断,这就导致业务代码不只健壮,还十分臃肿.其实 SpringBoot 中已经提供了 Valida

  • Springboot如何优雅地进行字段校验

    差不多大半年没写文章了,终于将手头上的事忙完了,可以对外输出了.前段时间提交代码审核,同事提了一个代码规范缺陷:参数校验应该放在controller层.到底应该如何做参数校验呢 Controller层 VS Service层 去网上查阅了一些资料,一般推荐与业务无关的放在Controller层中进行校验,而与业务有关的放在Service层中进行校验.那么如何将参数校验写的优雅美观呢,如果都是if - else,就感觉代码写的很low,还好有轮子可以使用 常用校验工具类 使用Hibernate V

  • Spring Boot 实现字段唯一校验功能(实例代码)

    目录 1 Maven依赖 2 实现代码 2.1 UniqueCheck 2.2 UniqueCheckDetail 2.3 UniqueCheckArgs 2.4 UniqueCheckService 2.5 AbstractUniqueCheckService 3 调试代码 3.1 UserCheckArgs 3.2 UserUniqueCheckVo 3.3 UserUniqueCheckService 3.4 UniqueCheckEnum 3.5 单元测试代码 4 调试结果 注: 1 M

  • AngularJs表单校验功能实例代码

    废话不多说了,具体代码如下所示: <!DOCTYPE html> <html ng-app="angularFormCheckModule"> <head> <meta charset="UTF-8"> <title>angular表单校验</title> <link rel="stylesheet" href="../css/bootstrap.min.cs

  • spring boot拦截器实现IP黑名单实例代码

    前言 最近一直在搞 Hexo+GithubPage 搭建个人博客,所以没怎么进行 SpringBoot 的学习.所以今天就将上次的"?秒防刷新"进行了一番修改.上次是采用注解加拦截器(@Aspect)来实现功能的.但是,如果需求是一个全局的拦截器对于大部分URL都进行拦截的话,自己一个个加显然是不可能的.而且上次的拦截器对于Controller的参数有所要求,在实际他人引用总是显得不方便.所以,这次使用了继承HandlerInterceptor来实现拦截器. 功能需求 对于项目中某类U

  • spring boot + mybatis实现动态切换数据源实例代码

    前言 前几天有个需求,需要使用不同的数据源,例如某业务要用A数据源,另一个业务要用B数据源.我上网收集了一些资料整合了一下,虽然最后这个需求不了了之了,但是多数据源动态切换还是蛮好用的,所以记录一下,或许以后有用呢?或者自己感兴趣又想玩呢! 下面话不多说了,随着小编来一起看看详细的介绍吧 方法如下: 1.加个依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybat

  • spring boot使用thymeleaf跳转页面实例代码

    前言 在学习springboot 之后想结合着html做个小demo,无奈一直没掌握窍门,在多番的搜索和尝试下终于找到了配置的方法,使用thymeleaf做事前端页面模板,不能使用纯html. thymeleaf介绍 Thymeleaf是面向Web和独立环境的现代服务器端Java模板引擎. Thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板 - 可以在浏览器中正确显示HTML,还可以作为静态原型工作,从而在开发团队中进行更强大的协作. 使用Spring Framework的模块,

  • spring boot+自定义 AOP 实现全局校验的实例代码

    最近公司重构项目,重构为最热的微服务框架 spring boot, 重构的时候遇到几个可以统一处理的问题,也是项目中经常遇到,列如:统一校验参数,统一捕获异常... 仅凭代码 去控制参数的校验,有时候是冗余的,但通过框架支持的 去控制参数的校验,是对于开发者很友好,先看下面的例子 @NotEmpty(message="手机号不能为空") @Size(min=11,max=11,message="手机号码长度不正确") @Pattern(regexp=StringUt

  • Spring请求参数校验功能实例演示

    SpringMVC支持的数据校验是JSR303的标准,通过在bean的属性上打上@NotNull.@Max等进行验证.JSR303提供有很多annotation接口,而SpringMVC对于这些验证是使用hibernate的实现,所以我们需要添加hibernate的一个validator包: 依赖引用 compile 'javax.validation:validation-api:2.0.0.Final' compile 'org.hibernate:hibernate-validator:6

  • Angular+Bootstrap+Spring Boot实现分页功能实例代码

    需要用到的js angular.js(用angular.min.js会导致分页控件不显示) ui-bootstrap-tpls.min.js angular-animate.js 需要用到的css bootstrap.min.css 由于本项目使用了路由,所以讲js以及css文件的应用都放在一个主html,请同学们在html页面中添加以上文件 在开始之前,我先简单介绍下分页的原理. 分页的实质其实就是一条sql语句, 比如查找第二页,即第16到第30条数据 在MySQL中是select * fr

  • Spring Boot项目传参校验的最佳实践指南

    目录 场景还原 神注解加持 数据异常统一拦截 总结 场景还原 简单业务场景模拟: 假如你现在在做一个成绩录入系统,你愉快地用Spring Boot框架写了一个后台接口,用于接收前台浏览器传过来的 Student对象,并插入后台数据库. 我们将传入的 Student对象定义为: public class Student { private String name; // 姓名 private Integer score; // 考试分数(满分100分) private String mobile;

  • Spring boot实现文件上传功能

    本文实例为大家分享了Spring boot实现文件上传的具体代码,供大家参考,具体内容如下 1. 创建一个Maven的web工程,然后配置pom.xml文件,增加依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.0.2.RELEASE</v

随机推荐