我在使用SpringBoot创建一个异常拦截器,我的代码如下
操作系统:macOS
Spring boot:2.1.0
JDK:11
private final Logger logger = LoggerFactory.getLogger(ExceptionFilterHandler.class);
/**
*
* 不能直接使用如下代码:
* fieldErrors.stream().collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage));
* 如果entity有类似于如下代码(对字段有多个校验条件):
* example code:
*
* @NotNull(message = Constant.IS_NULL)
* @NotBlank(message = Constant.IS_BLANK)
* @Length(message = Constant.ILLEGAL_LENGTH,min = 64,max = 64)
* private String fromAccount;
*
* 如果以上字段的校验条件没有通过俩个或者俩个以上,在封装错误信息时stream api会抛出 duplicate Key 异常
*/
@ExceptionHandler(Exception.class)
public Object violationException(BindingResult result) {
List<FieldError> fieldErrors = result.getFieldErrors();
logger.error("failed verify object : {} total of {} parameters failed to pass the inspection ",result.getObjectName(),result.getErrorCount());
Map<String, List<FieldError>> collect = fieldErrors.stream().collect(Collectors.groupingBy(FieldError::getField));
HashMap<String, Object> errorMsg = new HashMap<>(collect.size());
for (Map.Entry<String, List<FieldError>> entry : collect.entrySet()) {
List<String> list = entry.getValue().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.toList());
errorMsg.put(entry.getKey(),list);
}
return errorMsg;
}
如上的代码,有一个很大的缺陷就是有太多的循环(包扩stream Api的循环),这一点让我很难受
有没有再进一步的优化,哪怕提升一点点
emmm,感觉题主的意思,
groupBy
方法的Collector
接口参数传一个mapping
应该就可以了吧,类似这样毕竟你是想把按照
Field
分类的FieldError
里的信息再次转换为另外一个信息嘛,groupBy
只有一个参数那个默认的Collector
是Collectors.toList()
,所以相当于你要修改一下Collector
的实现罢了,这个mapping
方法也好理解,就是把里头的数据做一把转换,然后再传一个Collector
进去,表示如何收集,按你原来做法就是toList
,所以我也写了toList
就酱( σ'ω')σ