国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java自定義校驗注解實現(xiàn)List、set集合字段唯一性校驗

這篇具有很好參考價值的文章主要介紹了Java自定義校驗注解實現(xiàn)List、set集合字段唯一性校驗。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一: 使用場景

在開發(fā)過程中,前端給后端傳遞集合,并且需要保證集合的實體類中的某些字段必須是惟一的,不能重復。

傳遞的集合:

private List<User> userInfoList;

集合對應的實體類:

@Data
public class User {

    private int id;

    private String name;
    
    private String card;

}

如果我們要保證傳遞的name或者card必須是唯一的,不能重復,應該如何實現(xiàn)呢,此時可以通過自定義注解的方式實現(xiàn)。

二: 定義FieldUniqueValid注解

2.1 @FieldUniqueValid


/**
 * 該注解用于校驗List集合實體類當中的某些字段的唯一性
 * <p>
 * 條件表達式支持使用"$parent."獲取父節(jié)點屬性(實體內不能使用除List集合外的其他集合類型,例如Set等)
 * <ul>
 * <li>標記在字段上:用于指定單個或多個字段,fields需填寫</li>
 * </ul>
 * @author ikun
 * @date 2023.07.27
 */
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FieldUniqueValidator.class)
public @interface FieldUniqueValid {

    //需要進行唯一校驗的字段
    String[] fieldsCode() default{};

    String[] fieldsName() default{};

    String message() default "[fieldName]列[index]行數(shù)據(jù)重復";

    //不能有默認值,報錯:contains Constraint annotation, but the groups parameter default value is not the empty array
    Class<?>[] groups() default {};//在那種組中使用

    Class<? extends Payload>[] payload() default {};
}

2.2 注解說明

@Documented

@Document 是 java 在生成文檔,是否顯示注解的開關。

@Target(ElementType.FIELD)

ElementType.FIELD:該注解只能聲明在一個類的字段前。

2.3 @Constraint 注解介紹

@Constraint注解是Java Bean Validation框架中的一個注解,用于自定義約束注解,即自定義校驗規(guī)則。

通過在自定義注解上添加@Constraint注解,可以將該注解標記為一個自定義約束注解。同時,需要指定一個實現(xiàn)了ConstraintValidator接口的驗證器類,用于驗證該注解所標記的字段或參數(shù)是否符合自定義的校驗規(guī)則。

@Constraint注解有以下屬性:

  • validatedBy:用于指定實現(xiàn)了ConstraintValidator接口的驗證器類。該屬性的值是一個Class對象數(shù)組,可以指定多個驗證器類。

  • message:用于指定當校驗失敗時,所返回的錯誤信息。可以使用占位符{},在校驗器中使用具體的參數(shù)替換。

  • groups:用于指定分組,即根據(jù)不同的分組應用不同的校驗規(guī)則。

  • payload:用于指定元數(shù)據(jù),即可以通過該屬性傳遞一些額外的驗證信息。

使用@Constraint注解,可以通過自定義注解的方式,為字段或參數(shù)添加自定義的校驗規(guī)則,并實現(xiàn)校驗邏輯。這樣,在進行參數(shù)校驗時,可以方便地通過注解的方式來調用自定義的校驗規(guī)則。

2.4 @FieldUniqueValid注解使用

@FieldUniqueValid(fieldsCode = {"name,card"}, fieldsName = {"姓名,身份證號"})
private List<User> userInfoList;
  • fieldsCode :需要校驗的字段
  • fieldsName :校驗字段對應的名稱

三:自定義FieldUniqueValidator校驗類

@Slf4j
public class FieldUniqueValidator implements ConstraintValidator<FieldUniqueValid, Iterable<?>> {

    private String[] fieldsCode;

    private String[] fieldsName;

    /**
     * 數(shù)據(jù)有重復的字段名稱
     */
    private static final String FIELD_NAME= "[fieldName]";

    /**
     * 相同元素下標集合
     */
    private static final String INDEX = "[index]";

    /**
     * 初始化參數(shù)
     * @param constraintAnnotation 注解的值
     */
    @Override
    public void initialize(FieldUniqueValid constraintAnnotation) {
        fieldsCode = constraintAnnotation.fieldsCode();
        fieldsName = constraintAnnotation.fieldsName();
    }

    @Override
    public boolean isValid(Iterable<?> value, ConstraintValidatorContext context) {
        //如果沒有配置校驗字段信息,則直接通過
        if(fieldsCode.length == 0 && fieldsName.length == 0){
            return true;
        }
        if(fieldsCode.length != fieldsName.length){
            throw new RuntimeException("@FieldUniqueValid注解所對應的fieldsCode和fieldsName無法相互映射");
        }
        if(value == null){
            throw new RuntimeException("@FieldUniqueValid注解所在的集合為空,無法判斷");
        }
        for (int i = 0; i < fieldsCode.length; i++) {
            List<Object> list = new ArrayList<>();
            Iterator<?> iterator = value.iterator();
            long index;
            for (index = 0; iterator.hasNext(); index++) {
                Object fieldValue = null;
                try {
                    //forceAccess = true,屬性是私有的,需要設置為true打開權限
                    fieldValue = FieldUtils.readField(iterator.next(),fieldsCode[i],true);
                } catch (IllegalAccessException e) {
                    log.error(fieldsName[i] + "轉化失敗,無法進行校驗", e);
                }
                list.add(fieldValue);
            }
            //去重后的總數(shù)
            long count = list.stream().distinct().count();
            //去重之前和去重以后進行比較
            if(count < index){
                //返回重復元素下標集合
                String sameIndex = getListSameIndex(list);
                String defaultConstraintViolation = context.getDefaultConstraintMessageTemplate();
                context.disableDefaultConstraintViolation();
                String convertedConstraintViolation = defaultConstraintViolation.replace(FIELD_NAME, fieldsName[i]).replace(INDEX, sameIndex);
                context.buildConstraintViolationWithTemplate(convertedConstraintViolation).addConstraintViolation();
                return false;
            }
        }
        return true;
    }


}

3.1 實現(xiàn)ConstraintValidator

ConstraintValidator<FieldUniqueValid, Iterable<?>>:

  • FieldUniqueValid:需要校驗的注解,就是我們自定義的
  • Iterable<?>:前端傳遞list的類型,此時用Iterable是因為數(shù)據(jù)支持list和set集合

3.2 重寫initialize方法

可以從onstraintAnnotation參數(shù)中獲取fieldsCode、fieldsName里面的參數(shù)。主要作用就是將注解的參數(shù)進行初始化

3.3 重寫isValid方法

Iterable<?> value, ConstraintValidatorContext context

  • value:可以獲取到傳遞的集合數(shù)據(jù)
  • context:獲取注解上的message信息

3.4 獲取list集合重復數(shù)據(jù)的下標

/**
     * 集合【List】找出list中重復元素的下標(顯示下標所在位置)
     * @param list
     */
    public static String getListSameIndex(List<?> list){
        List<Object> same = new ArrayList<>();
        List<?> collect = list.stream().distinct().collect(Collectors.toList());
        if(collect.size() == list.size()){
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i <collect.size(); i++) {
            for (int j = 0; j < list.size(); j++) {
                if (list.get(j).equals(collect.get(i))){
                    same.add(j+1);
                }
            }
            if (same.size() > 1){
                sb.append(same).append("、");
            }
            same.clear();
        }
        return sb.substring(0, sb.toString().lastIndexOf("、"));
    }

3.5 思路

首先獲取到集合的數(shù)據(jù),然后通過反射,用循環(huán)遍歷獲取到name字段的list數(shù)據(jù),然后去重。將去重前后的list進行比較。如果長度變化了則說明有重復數(shù)據(jù)。此時返回false。然后我們我們通過getListSameIndex方法獲取到list重復數(shù)據(jù)的下標然后替換[index]。

3.6 測試

3.6.1 前端傳遞參數(shù),需要進行唯一性校驗的字段

Java自定義校驗注解實現(xiàn)List、set集合字段唯一性校驗,java,list,開發(fā)語言

3.6.2 message提示

Java自定義校驗注解實現(xiàn)List、set集合字段唯一性校驗,java,list,開發(fā)語言文章來源地址http://www.zghlxwxcb.cn/news/detail-627575.html

到了這里,關于Java自定義校驗注解實現(xiàn)List、set集合字段唯一性校驗的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Java集合(List、Set、Map)

    Java中的集合是用于存儲和組織對象的數(shù)據(jù)結構。Java提供了許多不同的集合類,包括List、Set和Map等,以滿足不同的需求。下面將介紹一些常見的Java集合類及其使用方法。 一、List List是一個有序的集合,它允許元素重復出現(xiàn),并提供了索引訪問元素的功能。List可以通過以下方

    2024年02月16日
    瀏覽(26)
  • Java的集合類:List、Set、Map

    在 Java 中,集合類是一組有序或無序的數(shù)據(jù)元素的集合。Java 集合類可用于存儲和操作各種數(shù)據(jù)類型的元素,如整數(shù)、字符串、對象等。集合類是動態(tài)的,可以在運行時根據(jù)需要調整其大小。 Java 集合類可以分為三類: List - 有序集合,允許重復元素 Set - 無序集合,不允許重

    2024年02月16日
    瀏覽(28)
  • Java-集合框架-List,Set,Map,隊列

    Java集合框架是一組用于存儲和操作數(shù)據(jù)的類和接口。它提供了不同類型的集合,如List,Set,Map和隊列,以滿足不同的需求。 List:有序的集合,允許重復的元素。 Set:無序的集合,不允許重復的元素。 Map:鍵值對的集合,每個元素都包含一個鍵和一個值。 隊列:先進先出(

    2024年02月11日
    瀏覽(51)
  • Java list集合中根據(jù)其中兩個字段去重

    可以使用Java 8的Stream API和Collectors.toSet()方法來實現(xiàn)根據(jù)其中兩個字段去重。 首先,使用Stream API將List轉換為Stream,然后使用distinct()方法進行去重。distinct()方法默認使用元素的equals()和hashCode()方法進行去重。如果想要根據(jù)其中兩個字段進行去重,需要重寫equals()和hashCode()方法

    2024年02月16日
    瀏覽(105)
  • java 對List集合中元素對象按字段分組,并收集指定字段的值

    java 對List集合中元素對象按字段分組,并收集指定字段的值

    一、實現(xiàn):對已有對象集合ListPersion ,需要獲取Persion對象的字段 name分組, 并對年齡age字段值做收集 二、字段分組收集方法 ?注:由于實際業(yè)務只有String類型跟數(shù)字類型,所以只對String跟Object兩種類型判空 三、測試代碼 四、結果

    2024年02月15日
    瀏覽(19)
  • Java基礎六 - Collection集合List、Set、Queue,Map

    1. List - ArrayList、LinkedList、Vector ArrayList ????????2. LinkedList ????????3.?Vector ????????4. 常見使用方法 2. Set - HashSet、LinkedHashSet、TreeSet 1.?HashSet 2. LinkedHashSet 3. TreeSet 4. 常用方法 3. Map -?HashMap、TreeMap、LinkedHashMap、Hashtable 1.?HashMap 2.?LinkedHashMap 3.?TreeMap 4.?Hashtable 5.

    2024年02月14日
    瀏覽(28)
  • Java中List對象集合按照對象中某字段進行排序

    在Java中,可以使用List集合對象的sort(Comparator? super E c)方法,按照對象中某字段對List集合進行排序 栗子: 打印輸出結果如下:

    2024年02月12日
    瀏覽(20)
  • 【JAVA】集合與背后的邏輯框架,包裝類,List,Map,Set,靜態(tài)內部類

    【JAVA】集合與背后的邏輯框架,包裝類,List,Map,Set,靜態(tài)內部類

    ?? Author: 老九 ?? 個人博客:老九的CSDN博客 ?? 個人名言:不可控之事 樂觀面對 ?? 系列專欄: Collection 接口,在 Java 當中,Collection 也是重要的數(shù)據(jù)結構。 在創(chuàng)建 Collection 的時候,要 通過 new 來使用。但是查看 Collection 源碼的時候, 發(fā)現(xiàn) Collecting 是一個接口

    2024年02月07日
    瀏覽(56)
  • 【Java 集合框架API接口】Collection,List,Set,Map,Queue,Deque

    【Java 集合框架API接口】Collection,List,Set,Map,Queue,Deque

    博主: _LJaXi Or 東方幻想郷 專欄: Java | 從跨行業(yè)到跨平臺 開發(fā)工具: IntelliJ IDEA 2021.1.3 Java集合API提供了一組功能強大的數(shù)據(jù)結構和算法, 具有以下作用( 簡述 ) 存儲和組織數(shù)據(jù) 提供高效的數(shù)據(jù)訪問和操作 實現(xiàn)算法和數(shù)據(jù)處理 提供線程安全性 支持泛型編程 java.util.Collection

    2024年02月12日
    瀏覽(32)
  • Java02-迭代器,數(shù)據(jù)結構,List,Set ,TreeSet集合,Collections工具類

    Java02-迭代器,數(shù)據(jù)結構,List,Set ,TreeSet集合,Collections工具類

    目錄 什么是遍歷? 一、Collection集合的遍歷方式 1.迭代器遍歷 方法 流程 案例 2. foreach(增強for循環(huán))遍歷 案例 3.Lamdba表達式遍歷 案例 二、數(shù)據(jù)結構 數(shù)據(jù)結構介紹 常見數(shù)據(jù)結構 棧(Stack) 隊列(Queue) 鏈表(Link) 散列表(Hash Table) 樹(Tree) List接口 ArraysList集合 Linked

    2024年02月14日
    瀏覽(54)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包