Kotlin で構築された Spring アプリケーションでは、次のようなデータ クラスで Bean 検証を使用したいと思います。
data class CustomerDto(
@field: NotBlank
val firstName: String,
@field: NotBlank
val lastName: String)
空の firstName を含む投稿を顧客エンドポイントに送信するときに、制約検証を取得したいのですが、フィールドが null 値を許可していないため、検証は取得されず、次のエラーが発生します。
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Instantiation of [simple type, class pkg.CustomerDto] value failed for JSON property firstName due to missing (therefore NULL) value for creator parameter firstName which is a non-nullable type; nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class pkg.CustomerDto] value failed for JSON property firstName due to missing (therefore NULL) value for creator parameter firstName which is a non-nullable type\n at [Source: (PushbackInputStream); line: 19, column: 1] (through reference chain: pkg.CustomerDto[\"firstName\"])",
"path": "/shop/5/customer"
dto フィールドをオプションではないとマークして、制約違反が発生する他のオプションはありますか? オプションとしてマークすると、エンティティにマッピングするときに、コード内の null 不可のフィールドに !! を使用する必要があります。
ありがとう。
ベストアンサー1
あなたは間違ったやり方で取り組んでいると思います。
Kotlin の null 安全演算子の正確な目的は、NPE を大幅に最小限に抑えるために、または少なくとも自分で意図的に NPE を発生させないようにするために、コード内で null 可能性の動作を明示的に表現するように強制することです :)。あなたの場合 (または MVC のようなアクセス パターンの場合)、次のシナリオに直面します。
- DTO ペイロードの一部としてフィールドが null になる可能性がある
- フィールドが null の場合、フレームワーク検証では DTO を不適格とする必要があります。
- フレームワークの検証が成功した場合、DTOフィールドは暗黙的に null ではないと想定される。
論理的な流れとしては理にかなっていますが、モデル/契約ではこれらのフィールドがnullにならないことを保証していないため、実際にはNPEを引き起こす可能性のある違反です。
それでも、Java では、getter を使用して最終的な仮定を行うことになります (Java なので、いずれにしても getter を使用するはずです)。
そうですね、それが必要なのであれば、Kotlin でも違いはありません。
data class CustomerDto(@field:NotNull
@JsonProperty("firstName") private val _firstName: String? = null,
@field:NotNull
@JsonProperty("lastName") private val _lastName: String? = null) {
val firstName get() = _firstName!!
val lastName get() = _lastName!!
}
(この例では、jackson
JSON のデシリアライゼーション/シリアル化に使用していることを前提としています)
演算子を使用して手動で非NULL可能性を強制しながら!!
(これは避けたいことでしたが)、その側面をコードベースの残りの部分から抽象化し、Javaのgetterのような動作を実現しています。