You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中使用mapper.readValue时缺失字段的校验方案

解决Kotlin数据类Jackson映射时的必填字段校验问题

在不修改数据类字段可空性的前提下,有几种实用的方式来校验JSON载荷是否包含所有必填属性:

1. 先解析为JsonNode手动校验

先把JSON字符串解析成Jackson的JsonNode,提前检查所有必填字段是否存在,避免直接映射时抛出异常:

val mapper = ObjectMapper().registerModule(KotlinModule())
val jsonPayload = """{"customerId": "C123", "purchaseDate": 1718000000000}"""

// 第一步:解析为JsonNode
val jsonNode = mapper.readTree(jsonPayload)

// 第二步:定义必填字段列表并检查
val requiredFields = listOf("purchaseId", "customerId", "purchaseDate")
val missingFields = requiredFields.filter { !jsonNode.has(it) }

if (missingFields.isNotEmpty()) {
    throw IllegalArgumentException("缺失必填字段:${missingFields.joinToString(", ")}")
}

// 第三步:校验通过后再映射到数据类
val example = mapper.treeToValue(jsonNode, Example::class.java)

这种方式完全可控,能自定义错误提示,还能扩展校验字段的有效性(比如检查字段是否为合法字符串/数字)。

2. 捕获Jackson的缺失字段异常

利用Jackson默认会抛出MismatchedInputException的特性,通过捕获异常来处理缺失字段的情况:

val mapper = ObjectMapper().registerModule(KotlinModule())
val jsonPayload = """{"customerId": "C123"}"""

try {
    val example = mapper.readValue(jsonPayload, Example::class.java)
    // 处理正常映射后的业务逻辑
} catch (e: MismatchedInputException) {
    // 从异常信息提取缺失字段,或给出通用提示
    val errorMsg = when {
        e.message?.contains("purchaseId") == true -> "缺失必填字段:purchaseId"
        e.message?.contains("customerId") == true -> "缺失必填字段:customerId"
        e.message?.contains("purchaseDate") == true -> "缺失必填字段:purchaseDate"
        else -> "JSON格式错误,缺失必填字段"
    }
    throw IllegalArgumentException(errorMsg)
}

如果想更通用提取缺失字段,可以解析异常的message内容,或者使用Jackson异常的e.path属性获取出错的属性路径。

3. 结合Bean Validation做增强校验

如果需要同时做格式、长度等多维度校验,可以引入Bean Validation框架(如Hibernate Validator)配合使用:

先给数据类字段添加校验注解:

import javax.validation.constraints.NotNull

data class Example(
    @NotNull val purchaseId: String,
    @NotNull val customerId: String,
    @NotNull val purchaseDate: Long
)

然后配置校验器,在映射完成后主动校验:

import javax.validation.Validation

val validator = Validation.buildDefaultValidatorFactory().validator

try {
    val example = mapper.readValue(jsonPayload, Example::class.java)
    val violations = validator.validate(example)
    if (violations.isNotEmpty()) {
        val errorMsg = violations.joinToString(", ") { "${it.propertyPath}:${it.message}" }
        throw IllegalArgumentException("校验失败:$errorMsg")
    }
    // 处理业务逻辑
} catch (e: MismatchedInputException) {
    throw IllegalArgumentException("缺失必填字段")
}

这种方式适合需要复杂校验规则的场景,能同时覆盖字段存在性和格式有效性校验。


内容的提问来源于stack exchange,提问作者joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 14:56:09