Spring MVC 将BindingResult检查从Controller移动到Aspect或Interceptor

xkrw2x1b  于 2023-11-22  发布在  Spring
关注(0)|答案(1)|浏览(170)

我在Controller中有多个multiple方法,每个方法都有一个ModelAttribute和一个BindingResult,例如

@RequestMapping(value = "/somewhere", method = RequestMethod.POST)
@ResponseBody
public SomeDTO someMethod(@Valid SomeModel someModel, BindingResult bindingResult, HttpServletRequest request,
        HttpServletResponse response) {

    if (bindingResult.hasErrors()) {
        throw new InvalidRequestException("some error", bindingResult);
    }

    SomeDTO someDTO = someService.doSomething(someModel);

    return someDTO;
}

字符串
我想稍微干燥一下我的代码,并将BindingResult检查放在类似AspectInterceptor.的东西中,换句话说,我不想在每个方法中都做以下检查:

if (bindingResult.hasErrors()) {
    throw new InvalidRequestException("some error", bindingResult);
}


每当在@Controller上调用一个方法时,我想检查BindingResult,如果有错误,那么抛出我的自定义InvalidRequestException。这样我的控制器就不需要检查。
我最初的想法是有一个方面来检查这一点:
伪代码

@Before("@within(org.springframework.stereotype.Controller)")
public void myMethod( JoinPoint jp ) throws Throwable {

    Signature signature = jp.getSignature();
    Object [] args = jp.getArgs();

    for(Object arg : args){
        if(arg instanceof BindingResult){
            BindingResult br = (BindingResult) arg;
            if(br.hasErrors()){
                throw new InvalidRequestException("Error...", br);
            }
        }
    }
}


但是我不确定这是否是一个好的方法来处理这个问题。有没有更简单的方法来做到这一点?或者Spring中的一些东西可以帮助做到这一点?
这背后的原因是,我有一个表单,提交了两个不同的ModelAttributes。所以每个方法都有两个BindingResults,这使得检查有点大,我实际上做了如下事情:

if (br1.hasErrors() || br2.hasErrors()) {
    List<Errors> errors = new ArrayList<Errors>();

    if(br1.hasErrors()){
        errors.add(br1);
    }

    if(br2.hasErrors()){
        errors.add(br2);
    }

    throw new InvalidRequestException("Error...", errors.toArray(new Errors[errors.size()]));
}


所以不必在每个方法中都进行这种检查会很好。

sqxo8psd

sqxo8psd1#

这个问题很古老,但如果能回答的话,我会节省很多时间,所以:
在我的Controller中,我有@Valid注解,这里不需要BindingResult

@PostMapping
public ResponseEntity<String> webHook(@Valid @RequestBody SomeDTO someDTO) {
    ...
}

字符串
然后我使用@ControllerAdvice来处理错误:

@ControllerAdvice
public class DtoValidationAdvice{

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationException(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach(error -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });

        return ResponseEntity.badRequest().body(errors);
    }
}

相关问题