我正在尝试将验证添加到Kotlin的数据模型中,使用@field
批注很容易实现简单的字段。但是,我正在努力对收藏进行同样的处理。
我已将问题上传到github here
java模型运行正常,但kotlin版本无效。我在这里添加两个模型。
public class JavaUser {
@NotEmpty
@NotNull
@Pattern(regexp = "[a-z]*", message = "Only lower case first name")
private String name;
private List<
@NotNull
@NotEmpty
@Pattern(regexp = "\\d{10}", message = "Only 10 digits")
String> phones;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getPhones() {
return phones;
}
public void setPhones(List<String> phones) {
this.phones = phones;
}
}
data class KotlinUser(
@field:NotEmpty
@field:NotNull
@field:Pattern(regexp = "[a-z]*", message = "Only lower case first name")
val name: String,
// Cannot use @field here, anything else we could use?
val phones: List<
@NotNull
@NotEmpty
@Pattern(regexp = "\\d{10}", message = "Only 10 digits")
String>
)
我的测试-Java测试通过,但kotlin一次失败
@Test
fun `java user validation`() {
val javaUser = JavaUser()
javaUser.name = "sadfjsjdfhsjdf"
javaUser.phones = listOf("dfhgd")
webTestClient.put().uri("/user/java")
.body(BodyInserters.fromObject(javaUser))
.exchange()
.expectStatus().is4xxClientError
}
@Test
fun `kotlin user validation`() {
val kotlinUser = KotlinUser(name = "sadfjsjdfhsjdf", phones = listOf("dfhgd"))
webTestClient.put().uri("/user/kotlin")
.body(BodyInserters.fromObject(kotlinUser))
.exchange()
.expectStatus().is4xxClientError
}
控制器
@RestController
class Controller {
@PutMapping("/user/java")
fun putUser(@RequestBody @Valid javaUser: JavaUser): Mono<ResponseEntity<String>> =
Mono.just(ResponseEntity("shouldn't get this", HttpStatus.OK))
@PutMapping("/user/kotlin")
fun putUser(@RequestBody @Valid kotlinUser: KotlinUser): Mono<ResponseEntity<String>> =
Mono.just(ResponseEntity("shouldn't get this", HttpStatus.OK))
}
任何帮助将不胜感激。谢谢!
答案 0 :(得分:4)
当前不支持此功能。 Kotlin编译器当前忽略类型的注释。
查看详情:
在Kotlin问题跟踪器上也有与此相关的问题:
后者的目标版本为1.4
。
答案 1 :(得分:1)
尝试一下:
data class KotlinUser(
@field:NotEmpty
@field:NotNull
@field:Pattern(regexp = "[a-z]*", message = "Only lower case first name")
val name: String,
@field:Valid
@field:NotEmpty
val phones: List<Phone>
)
data class Phone(
@NotBlank
@Pattern(regexp = "\\d{10}", message = "Only 10 digits")
val phoneNumber: String?
)
答案 2 :(得分:0)
如果您不坚持使用Bean验证,可以选择YAVI。
您可以定义验证,如下所示:
import am.ik.yavi.builder.ValidatorBuilder
import am.ik.yavi.builder.forEach
import am.ik.yavi.builder.konstraint
data class KotlinUser(val name: String,
val phones: List<String>) {
companion object {
val validator = ValidatorBuilder.of<KotlinUser>()
.konstraint(KotlinUser::name) {
notEmpty()
.notNull()
.pattern("[a-z]*").message("Only lower case first name")
}
.forEach(KotlinUser::phones, {
constraint(String::toString, "value") {
it.notNull().notEmpty().pattern("\\d{10}").message("Only 10 digits")
}
})
.build()
}
}
Here是代码的YAVI版本。
答案 3 :(得分:0)
一种解决方法是在控制器中使用spring的@Validated
。
示例:
@RestController
@RequestMapping("/path")
@Validated
class ExampleController {
@PostMapping
fun registerReturns(@RequestBody @Valid request: List<@Valid RequestClass>) {
println(request)
}
}
RequestClass:
@JsonIgnoreProperties(ignoreUnknown = true)
data class RequestClass(
@field:NotBlank
val field1: String?,
@field:NotBlank
@field:NotNull
val field2: String?)
以这种方式应用Beans验证。