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

Spring Boot注解校验List元素时获取违规项索引自定义错误响应

解决方案

你当前已经拿到了带列表索引标记的字段错误路径,只需要完成排序、索引提取、消息格式化三步即可实现预期效果,注意不要用无序的HashMap存储错误集合,会打乱返回顺序。

核心处理逻辑

  • 对所有字段错误按列表索引升序排序,保证错误返回顺序和入参列表顺序一致
  • 通过正则从字段名(格式为contact[x].email)中提取元素索引,转换为从1开始计数的日常序号
  • 把序号拼接到对应错误提示文本中,最终用有序List存储格式化后的错误信息

完整修改后的异常处理器代码

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.*;

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
    Map<String, Object> body = new LinkedHashMap<>();
    body.put("timestamp", new Date());
    body.put("status", HttpStatus.BAD_REQUEST.value());

    // 正则匹配字段路径中的列表索引
    Pattern indexPattern = Pattern.compile("contact\\[(\\d+)\\]");

    List<String> errors = ex.getBindingResult().getFieldErrors().stream()
            // 按列表索引升序排序
            .sorted(Comparator.comparingInt(e -> extractIndex(e.getField(), indexPattern)))
            // 格式化错误消息
            .map(fieldError -> {
                int seq = extractIndex(fieldError.getField(), indexPattern) + 1;
                String rawMsg = fieldError.getDefaultMessage();
                return rawMsg.replace("E-mail address ", String.format("E-mail address %d: ", seq));
            })
            .collect(Collectors.toList());

    body.put("errors", errors);
    return body;
}

// 提取字段路径中的列表索引值
private int extractIndex(String fieldPath, Pattern pattern) {
    Matcher matcher = pattern.matcher(fieldPath);
    return matcher.find() ? Integer.parseInt(matcher.group(1)) : 0;
}

最终返回效果

修改后接口返回格式完全符合预期:

{
    "timestamp": "2022-06-16T00:43:50.878+00:00",
    "status": 400,
    "errors": [
        "E-mail address 1: 'tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com' must be between 0 and 20 characters long",
        "E-mail address 2: 'tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com' must be between 0 and 20 characters long"
    ]
}

可选优化

  • 如果后续有其他嵌套列表的校验场景,可以调整正则规则,不写死contact字段名,通用提取所有[数字]格式的索引值
  • 如果错误消息前缀不固定,可以调整消息拼接逻辑,直接把序号追加到消息最前端即可,不需要做字符串替换

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:30:58