中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

在SpringBoot中怎么驗證輸入請求的自定義注解

發布時間:2022-02-25 15:09:53 來源:億速云 閱讀:224 作者:小新 欄目:開發技術

這篇文章主要介紹了在SpringBoot中怎么驗證輸入請求的自定義注解,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

在我們的日常編程中,我們會使用許多可用于驗證的 Spring Boot 默認注解,如@NotNull、@Size、@NotBlank、@Digits等等,這是驗證任何傳入的一種很酷的方式要求。

考慮一個場景,默認情況下有一些字段是可選的,如果其他一些字段由特定值填充,則它必須是強制性的。 

Spring 沒有為這種驗證預定義注釋。

讓我們舉一些例子,看看我們如何簡化驗證過程,使其代碼可重用,并在注釋級別引入抽象。 

在一個典型的銷售平臺中,會有銷售操作和無效銷售操作。該金額在銷售操作中是強制性的,在銷售操作無效的情況下,沖銷類型將是強制性的。 

我們的 dto 類如下:

public class IncomingRequestDto {    
    public TransactionType transactionType;
    public ReversalType reversalType;
    public String reversalId;
    public AmountDto amountDto;
}

IncomingRequestDto 有幾個屬性,如 transactionType、reversalType 作為 ENUMS。

public enum TransactionType {
    SALE {
        public String toString() {
            return "Sale";
        }
    },
    VOIDSALE {
        public String toString() {
            return "VoidSale";
        }
    },
}
public enum ReversalType {
    TIMEDOUT {
        public final String toString() {
            return "Timedout";
        }
    },
    CANCELLED {
        public final String toString() {
            return "Cancelled";
        }
    }
}

和 amountDto 為:

public class AmountDto {    
    public String value;
}

場景一: amountDto.value 是有條件的。當我們收到一個具有 transactionType="SALE" 的請求時,amountDto.value 應該是強制性的。

場景 2: reversalType 是有條件的。當我們收到一個具有 transactionType="VOIDSALE" 的請求時,reversalType 應該是強制性的。 

讓我們首先定義一個帶有驗證過程所需屬性的注釋:

@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
public @interface NotNullIfAnotherFieldHasValue {
    String fieldName();
    String fieldValue();
    String dependFieldName();
    String message();
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        NotNullIfAnotherFieldHasValue[] value();
    }
}

fieldName 和 fieldValue 將被定義,我們必須在其上搜索特定值。這里是“銷售”。

將定義dependFieldName,我們必須在其上搜索值。 

現在讓我們實現上面的接口:

public class NotNullIfAnotherFieldHasValueValidator
        implements ConstraintValidator<NotNullIfAnotherFieldHasValue, Object> {
    private String fieldName;
    private String expectedFieldValue;
    private String dependFieldName;
    @Override
    public void initialize(NotNullIfAnotherFieldHasValue annotation) {
        fieldName = annotation.fieldName();
        expectedFieldValue = annotation.fieldValue();
        dependFieldName = annotation.dependFieldName();
    }
    @Override
    public boolean isValid(Object value, ConstraintValidatorContext ctx) {
        String fieldValue = "";
        String dependFieldValue = "";
        if (value == null) {
            return true;
        }
        try {
            fieldValue = BeanUtils.getProperty(value, fieldName);
            dependFieldValue = BeanUtils.getProperty(value, dependFieldName);
            return validate(fieldValue, dependFieldValue, ctx);
        } catch (NestedNullException ex) {
            dependFieldValue = StringUtils.isNotBlank(dependFieldValue) ? dependFieldValue : "";
            try {
                return validate(fieldValue, dependFieldValue, ctx);
            } catch (NumberFormatException exception) {
                return false;
            }
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | NumberFormatException | NullPointerException ex) {
            return false;
        }
    }
    private boolean validate(String fieldValue,
                             String dependFieldValue, ConstraintValidatorContext ctx) {
        if (!StringUtils.isBlank(fieldValue)) {
             if (expectedFieldValue.equals(fieldValue) && (StringUtils.isBlank(dependFieldValue))) {
                ctx.disableDefaultConstraintViolation();
                ctx.buildConstraintViolationWithTemplate(ctx.getDefaultConstraintMessageTemplate())
                        .addNode(dependFieldName)
                        .addConstraintViolation();
                return false;
            }
        } else {
            return false;
        }
        return true;
    }
}

在這里,我們需要返回并使用其實現類裝飾我們的界面,如下所示:

@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)@Constraint(validatedBy = NotNullIfAnotherFieldHasValueValidator.class)@Documented
public @interface NotNullIfAnotherFieldHasValue {

就是這樣!我們已經完成了!讓我們用我們的自定義注解裝飾我們的 IncomingRequestDto 類:

@JsonDeserialize(as = IncomingRequestDto.class)@NotNullIfAnotherFieldHasValue.List({
        @NotNullIfAnotherFieldHasValue(
                fieldName = "transactionType",
                fieldValue = "Sale",
                dependFieldName = "amountDto.value",
                message = " - amount is mandatory for Sale requests"),        
})@JsonInclude(JsonInclude.Include.NON_NULL)
public class IncomingRequestDto {
    public TransactionType transactionType;
    public ReversalType reversalType;
    public String reversalId;
    public AmountDto amountDto;

}

通過添加上述注釋,請求將被拒絕為BAD,HTTP 400不為 Sale 類型請求填充 amountDto.value。我們可以在 List 中添加任意數量的驗證,而無需更改任何代碼,如下所示:

@JsonDeserialize(as = IncomingRequestDto.class)
@NotNullIfAnotherFieldHasValue.List({@NotNullIfAnotherFieldHasValue(
                fieldName = "transactionType",
                fieldValue = "Sale",
                dependFieldName = "amountDto.value",
                message = " - amount is mandatory for Sale requests"),
        @NotNullIfAnotherFieldHasValue(
                fieldName = "transactionType",
                fieldValue = "VoidSale",
                dependFieldName = "reversalType",
                message = " - Reversal Type is mandatory for VoidSale requests"),})
@JsonInclude(JsonInclude.Include.NON_NULL)
public class IncomingRequestDto {
    public TransactionType transactionType;
    public ReversalType reversalType;
    public String reversalId;
    public AmountDto amountDto;

}

感謝你能夠認真閱讀完這篇文章,希望小編分享的“在SpringBoot中怎么驗證輸入請求的自定義注解”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

攀枝花市| 科尔| 邹平县| 涿鹿县| 高尔夫| 海晏县| 齐河县| 侯马市| 平凉市| 邹城市| 九台市| 湖南省| 新和县| 溧阳市| 越西县| 太保市| 巴林左旗| 万年县| 当涂县| 天台县| 上饶县| 禹州市| 甘孜县| 保靖县| 永顺县| 余干县| 嵊州市| 方正县| 达日县| 宜都市| 偏关县| 辽阳县| 左贡县| 新化县| 凌海市| 道孚县| 庆元县| 资源县| 介休市| 奉新县| 南澳县|