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

如何通过Java Bean Validation确保quantity仅接受数值输入?

问题与解决方案

问题背景

我有一个用于接收请求体的Java类ItemForReorderRequest,代码如下:

public class ItemForReorderRequest {
    private String itemNo;
    @DecimalMax(value = "100", message = "Reorder quantity must be less than or equal to 100")
    private Double quantity;
}

合法请求体示例:

{
        "itemNo": "000006510",
        "quantity": 100.0
}

需求是验证quantity字段仅接受数值输入,但当向该字段传入字符串时,系统抛出An unexpected application error has occurred通用异常,错误栈包含com.fasterxml.jackson.core.JsonParser相关内容。

问题根源

Jackson在反序列化JSON请求体时,遇到类型不匹配(字符串转Double)直接抛出解析异常,此时Bean Validation(如@DecimalMax)的校验逻辑还未触发,导致返回的是系统级通用错误而非参数校验错误。

解决方案

1. 配置Jackson禁用字符串转数值,开启严格类型检查

修改Jackson配置,禁止将字符串自动转换为数值,同时开启严格的类型校验,让Jackson在类型不匹配时抛出明确的解析错误:

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 禁用字符串自动转为数值的特性
        objectMapper.disable(DeserializationFeature.ACCEPT_STRING_FOR_NUMBER);
        // 开启严格类型检查,遇到无效类型直接抛出异常
        objectMapper.enable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);
        return objectMapper;
    }
}

2. 全局捕获Jackson解析异常,返回友好响应

通过Spring的全局异常处理器,捕获Jackson的解析异常,返回自定义的400错误提示:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(JsonParseException.class)
    public ResponseEntity<Map<String, String>> handleJsonParseError(JsonParseException ex) {
        Map<String, String> errorResp = new HashMap<>();
        errorResp.put("code", "INVALID_PARAM_TYPE");
        errorResp.put("message", "quantity字段必须为数值类型");
        return ResponseEntity.badRequest().body(errorResp);
    }

    // 保留Bean Validation异常的处理逻辑,处理@DecimalMax等校验规则
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationErrors(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> 
            errors.put(error.getField(), error.getDefaultMessage())
        );
        return ResponseEntity.badRequest().body(errors);
    }
}

3. 确保Controller参数校验生效

在接收请求的Controller方法中,给请求体参数添加@Valid注解,触发Bean Validation的校验逻辑:

@PostMapping("/items/reorder")
public ResponseEntity<Void> submitReorder(@Valid @RequestBody ItemForReorderRequest request) {
    // 执行业务逻辑
    return ResponseEntity.ok().build();
}

经过以上配置,当quantity传入字符串时,系统会返回明确的400错误和友好提示,而非通用系统异常;同时@DecimalMax的校验规则也能正常触发。

内容的提问来源于stack exchange,提问作者G.D. Nipuna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:01:39