Spring Data REST docs描述了 RepositoryEventHandler
被解雇后验证实体的方法:
您只需要在其中注册验证器的实例 bean的工作是在正确的事件之后调用验证器
有没有办法在实体之前应用[声明式] JSR-303验证,然后将它们传递给" beforeSave" RepositoryEventHandler
S'
从目前为止我看到的调试情况来看,情况并非如此,并且" beforeSave"在进行任何验证之前,RepositoryEventHandler
会被解雇。
我可以直接在处理程序中编写验证调用,但这与"之后"验证得到处理。
顺便说一下。事件处理程序调用的序列似乎在Spring Boot 1.3.8和1.5.1之间发生了变化。过去,验证在 @HandleBeforeSave
处理程序之前发生。在 ValidatingRepositoryEventListener
处理程序之后的1.5.1 @HandleBeforeSave
解雇中。
更新
正如评论中所提到的,Spring Data REST中似乎有一个ticket Jira对此持开放态度。
答案 0 :(得分:2)
作为解决方法:
创建扩展X
的{{1}}并使用PreflightValidatingRepositoryEventListener
对其进行注释。
ValidatingRepositoryEventListener
添加与@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class PreflightValidatingRepositoryEventListener extends ValidatingRepositoryEventListener {
public PreflightValidatingRepositoryEventListener(ObjectFactory<PersistentEntities> persistentEntitiesFactory) {
super(persistentEntitiesFactory);
}
}
注意:验证将运行两次
答案 1 :(得分:2)
作为替代解决方法,这里有一个完全基于this示例的验证方面(稍作修改)。不要忘记添加@EnableAspectJAutoProxy
来激活方面并将其放入扫描Spring配置的包中。
@Aspect
@Component
public class RestRepositoryValidationAspect {
@Autowired
private Validator validator;
@Pointcut("@annotation(org.springframework.data.rest.core.annotation.HandleBeforeCreate)")
private void beforeCreateInvocation() {
}
@Pointcut("@annotation(org.springframework.data.rest.core.annotation.HandleBeforeSave)")
private void beforeSaveInvocation() {
}
@Around("beforeCreateInvocation() || beforeSaveInvocation()")
public Object validateBeforeRepostioryEventHandler(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
Annotation[][] argAnnotations = method.getParameterAnnotations();
String[] argNames = methodSignature.getParameterNames();
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
if (hasValidAnnotations(argAnnotations[i])) {
validateArg(args[i], argNames[i]);
}
}
return joinPoint.proceed(args);
}
private boolean hasValidAnnotations(Annotation[] annotations) {
if (annotations.length < 1) {
return false;
}
for (Annotation annotation : annotations) {
if (Valid.class.isInstance(annotation)) {
return true;
}
}
return false;
}
private void validateArg(Object arg, String argName) {
BindingResult result = getBindingResult(arg, argName);
validator.validate(arg, result);
if (result.hasErrors()) {
throw new RepositoryConstraintViolationException(result);
}
}
private BindingResult getBindingResult(Object target, String targetName) {
return new BeanPropertyBindingResult(target, targetName);
}
}
需要验证的存储库事件处理程序参数必须标有@Valid
注释,例如
@HandleBeforeSave
public void handleSave(@Valid MyEntity myEntity) {
...
}