我有一個data class我需要驗證的:
import javax.validation.Valid
import whatever.pckg.validation.PkiSignWithBusinessCode
import whatever.pckg.validation.NullOrNotBlank
data class UploadFileReq(
val id: String? = null,
...(other fields)...
@get:Valid
val signaturesInfo: MutableList<Pair<SignatureInfo, Object>> = mutableListOf() # Object here is for simplicity
) {
@PkiSignWithBusinessCode
data class SignatureInfo(
val typeSign: String = "",
@get:NullOrNotBlank
val businessCode: String? = null,
)
}
@NullOrNotBlank注釋只是標準@NotBlank和@Null注釋的簡單合并。
我還有另一個自定義驗證注解@PkiSignWithBusinessCode,它的定義如下:
import whatever.pckg.UploadFileReq
import javax.validation.*
import kotlin.annotation.AnnotationRetention.RUNTIME
import kotlin.reflect.KClass
@Constraint(validatedBy = [PkiSignWithBusinessCodeValidator::class])
@Target(AnnotationTarget.CLASS)
@Retention(RUNTIME)
annotation class PkiSignWithBusinessCode(
val message: String = "PKI signature requires filled businessCode",
val groups: Array<KClass<*>> = [],
val payload: Array<KClass<out Payload>> = []
)
class PkiSignWithBusinessCodeValidator: ConstraintValidator<PkiSignWithBusinessCode, UploadFileReq.SignatureInfo>> {
override fun isValid(obj: UploadFileReq.SignatureInfo?, context: ConstraintValidatorContext): Boolean {
if (obj != null) {
if ((obj.typeSign == "PKI") && (obj.businessCode == null)) {
return false
}
}
return true
}
上述注釋的邏輯非常簡單——當typeSign等于PKI和businessCode是時null,驗證器應該將其視為無效物件。
供您參考,這里有一個簡單的單元測驗,它試圖檢查以下作業@PkiSignWithBusinessCode:
import org.junit.jupiter.api.Test
import whatever.pckg.UploadFileReq
import javax.validation.Validation
import kotlin.test.assertEquals
class PkiSignWithBusinessCodeTest {
@Test
fun `validate PkiSignWithBusinessCodeTest`() {
val validator = Validation.buildDefaultValidatorFactory().validator
val signatureInfo = UploadFileReq.SignatureInfo(
typeSign = "PKI",
businessCode = null
)
val uploadFileReq = UploadFileReq(
null,
signaturesInfo = mutableListOf(signatureInfo to Object)
)
val result = validator.validate(uploadFileReq)
assertEquals(1, result.size)
assertEquals("PKI signature requires filled businessCode", result.first().messageTemplate)
}
}
但是這個測驗顯然在第一個斷言狀態下失敗:java.lang.AssertionError: Expected <1>, actual <0>.所以驗證器沒有發現約束違規。
問題是Spring忽略了上述注釋的驗證規則。作為一個假設,我認為Pair類包裝以某種方式阻止Spring使用我的驗證注釋。也許這是一個錯誤?
或者,也許我忽略了代碼中的某些內容?
uj5u.com熱心網友回復:
找到了一個解決方法 - 需要ValidatingPair使用@Valid注釋first和second這個新成員來制作自己的Pair:
import javax.validation.Valid
data class ValidatingPair<out A, out B>(
@get:Valid
public val first: A,
@get:Valid
public val second: B
) : java.io.Serializable {
override fun toString(): String = "($first, $second)"
}
和做:
val signaturesInfo: MutableList<Pair<SignatureInfo, Object>>
成為
val signaturesInfo: MutableList<ValidatingPair<SignatureInfo, Object>>
然后驗證開始對串列成員起作用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/491525.html
下一篇:如果欄位為空,是的驗證不顯示錯誤
