如何去除Spring MethodValidationInterceptor校验消息中的方法与Bean前缀?
去除Spring方法校验错误消息中的方法与Bean前缀
可以通过以下几种方式实现:
1. 捕获异常后手动处理错误消息
在捕获ConstraintViolationException时,提取属性路径的最后一段(即原始字段名),重新拼接错误消息:
try { // 调用带@Valid的方法 } catch (ConstraintViolationException e) { List<String> cleanErrors = e.getConstraintViolations().stream() .map(violation -> { String fullPath = violation.getPropertyPath().toString(); // 截取最后一个点之后的字段名 String fieldName = fullPath.substring(fullPath.lastIndexOf('.') + 1); return fieldName + ": " + violation.getMessage(); }) .collect(Collectors.toList()); // 可将cleanErrors用于返回或抛出自定义异常 throw new RuntimeException(String.join("; ", cleanErrors)); }
2. 自定义MethodValidationInterceptor重写错误处理逻辑
继承Spring的MethodValidationInterceptor,重写processConstraintViolations方法,修改错误消息的格式:
public class CleanMessageMethodValidationInterceptor extends MethodValidationInterceptor { @Override protected void processConstraintViolations(Set<ConstraintViolation<Object>> violations) { if (!violations.isEmpty()) { List<String> formattedMessages = violations.stream() .map(v -> { String propPath = v.getPropertyPath().toString(); String simpleField = propPath.substring(propPath.lastIndexOf('.') + 1); return simpleField + ": " + v.getMessage(); }) .collect(Collectors.toList()); throw new ConstraintViolationException(String.join(", ", formattedMessages), violations); } } }
然后配置MethodValidationPostProcessor使用自定义拦截器:
@Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor(); postProcessor.setMethodValidationInterceptor(new CleanMessageMethodValidationInterceptor()); return postProcessor; }
3. 使用自定义MessageInterpolator(进阶)
实现MessageInterpolator接口,在解析消息时去除方法和Bean前缀:
public class CleanMessageInterpolator implements MessageInterpolator { private final MessageInterpolator delegate; public CleanMessageInterpolator(MessageInterpolator delegate) { this.delegate = delegate; } @Override public String interpolate(String messageTemplate, Context context) { String originalMessage = delegate.interpolate(messageTemplate, context); // 移除方法和Bean前缀,比如从"save.entity.id: must not be null"提取"id: must not be null" if (originalMessage.contains(":")) { int lastColonIndex = originalMessage.lastIndexOf(':'); String fieldPart = originalMessage.substring(0, lastColonIndex); String messagePart = originalMessage.substring(lastColonIndex); String simpleField = fieldPart.substring(fieldPart.lastIndexOf('.') + 1); return simpleField + messagePart; } return originalMessage; } @Override public String interpolate(String messageTemplate, Context context, Locale locale) { return interpolate(messageTemplate, context); } }
然后配置Validator使用该插值器:
@Bean public Validator validator() { ValidatorFactory factory = Validation.byDefaultProvider() .configure() .messageInterpolator(new CleanMessageInterpolator(new DefaultMessageInterpolator())) .buildValidatorFactory(); return factory.getValidator(); } @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor(); postProcessor.setValidator(validator()); return postProcessor; }
内容的提问来源于stack exchange,提问作者MelleD
相关产品推荐
相关产品推荐

