反射获取ConstraintViolationException中的PropertyPath属性路径最后一个节点
Posted 花伤情犹在
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射获取ConstraintViolationException中的PropertyPath属性路径最后一个节点相关的知识,希望对你有一定的参考价值。
默认获取属性路径
示例代码
@ExceptionHandler(ConstraintViolationException.class)
public Object handleMethodArgumentNotValidException(ConstraintViolationException e)
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
if (CollectionUtils.isNotEmpty(violations))
violations.getPropertyPath(); // 获取属性路径
violations.getMessage(); // 获取错误信息
示例图
可以看到字段属性路径用于展示哪个字段有问题非常丑陋,例如test.student.addressId这个属性路径,我只需要知道是 addressId这个属性字段有问题就OK,前面多余的路径不想要,可以进入源码来查看propertyPath到底是个啥:
-
调用getPropertyPath
-
发现propertyPath其实是个Path
-
Ctrl+Alt+B查看Path的实现类是PathImpl
-
查看toString()方法,发现调用asString()
-
查看asString(),发现内部其实遍历nodeList这个集合
-
多个路径节点源码中是使用.来分割的,PROPERTY_PATH_SEPARATOR这个常量其实就一个点专门用来分割多个路径节点
得出结论
如果只想从路径节点(nodeList)中只拿到属性名称,我们只需要取出最后一位节点即可,而nodeList这个路径节点集合属性属于私有变量,所以需要采取反射暴力获取到nodeList这个属性,然后去最后一位即可。
示例代码
@ExceptionHandler(ConstraintViolationException.class)
public Object handleMethodArgumentNotValidException(ConstraintViolationException e)
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
if (CollectionUtils.isNotEmpty(violations))
Map map = new HashMap<>();
violations.stream().forEach(x->
List<Path.Node> nodeList = ReflectUtils.getFieldValue(x.getPropertyPath(),"nodeList");
map.put(nodeList.get(nodeList.size() - 1).getName(),x.getMessage());
);
return ...;
return ...;
ReflectUtils.getFieldValue(x.getPropertyPath(),"nodeList")
:反射暴力拿到nodeList nodeList.get(nodeList.size()-1.getName()
: 使用size()
方法获取长度减去1即可获取到最后一位节点,最后调用getName()
即可拿到节点名称也就是属性名称
以上是关于反射获取ConstraintViolationException中的PropertyPath属性路径最后一个节点的主要内容,如果未能解决你的问题,请参考以下文章