java - @Valid @NotNull组合无法生效

查看:2305
本文介绍了java - @Valid @NotNull组合无法生效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

Controller:

@PostMapping("/save")
public CommonResp saveMessage(@Valid MessageModel messageModel, Errors errors) {

    messageService.save(messageModel.toEntity());

    return new CommonResp(0, "success");
}

Model:

public class MessageModel implements Serializable, Cloneable {

    private static final long serialVersionUID = -7898194272883238672L;

    // 读写锁
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    private String id;

    @NotNull
    private Date createTime;
    
    // ...
    
    // getters/setters
}

然后请求的时候什么参数也没传,但是NotNull也不检查就直接通过了,直接到了Controller里面的断点。

关键是前两天还是正常的。。突然就这样。

不知道这套注解使用起来是需要有什么注意的吗,比如没有设置什么或者多余设置了什么就无法生效之类的。

解决方案

解决了,自问自答一下 -,-

首先这套注解的原始使用方式应该是下面这样:

@PostMapping("/valid")
public String valid(@Valid TestModel testModel) {
    return "success";
}

这样写是完全可以生效的(和我提问时的区别在于没有使用切面)。不过问题在于,如果使用这种方法,当参数不符合验证规则时,会报400错误,如下:

这样对于实际业务流程来说也许不够友好。所以一般的做法是使用切面环绕Controller方法,当有错误报出时,使用指定的处理逻辑。这样处理的话,当请求参数不符合验证规则时,会变成下面这样:

这样显然就会友好多了。
然而问题就出在切面这里。我提问时,针对Controller方法的切面定义代码如下:

@Aspect
public class FieldValidation {

    @Pointcut("execution(* com.spring_test.controller.*.*(.., org.springframework.validation.Errors))")
    public void aspect() {}

    @Around("aspect()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object[] objects = pjp.getArgs();
        Errors errors = (Errors) objects[objects.length - 1];
        if (errors.hasErrors()) {
            String msg = CommonUtil.errorMessage(errors);
            return CommonUtil.commonResponse(1, msg);
        }
        return pjp.proceed();
    }

}

没错,问题就是切面没有加

@Component

注解。。

只要给切面加上@Component注解,或者取消掉Controller方法和切面的匹配,就可以正常生效了。

虽说最后发现是粗心导致的问题,不过为什么切面错误时原本的@Valid也会失效呢?直觉上这两个没什么冲突才对,切面只是处理了@Valid时的错误,为什么切面错误时@Valid也并不报错了呢?

这点问题尚未解决,如果有dalao有兴趣,烦请指教,感谢~

这篇关于java - @Valid @NotNull组合无法生效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆