SpringBoot不在使用@Validated 做参数校验但是不想在Controller层怎么办?

目录

场景再现:

怎么做?

遇到了什么问题?

怎么实现?


场景再现:

某API接口接受加密的json字符串,接受字符串之后先进行解密处理,解密完成之后还要进行参数校验处理,如果参数不合规范会直接返回提示信息。

怎么做?

我们完全可以中规中矩的,先在controller层接受字符串,然后解密,然后在serivce层参数校验,但是这里有个问题,那就是解密后的json字符串将变成一个对象,然后这个对象中的字段却十分的多几十来个,如果使用普通的方法校验,每个参数都需要一个if语句,那该是多磨的可怕呀!!所以我考虑借助Validated 辅助我进行参数校验。

遇到了什么问题?

问题就是我们平常使用Validated 参数校验是是直接在controller层进行校验的比如这样。

    @PostMapping("/resume-info")
    public ResponseResult
    insertResumeInfo(@Validated(ValidatedGroup.Insert.class) @RequestBody ResumeMainInfoDTO dto) {
        return resumeInfoService.InsertInfo(dto);
    }
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResumeMainInfoDTO {

    @NotBlank(message = "!",groups = ValidatedGroup.Update.class)
    private Long id;

    /**
     * 姓名
     */
    @Length(max = 20,message ="!",groups = ValidatedGroup.Select.class)
    @NotBlank(message = "!",groups = ValidatedGroup.Insert.class)
    @NotBlank(message = "!",groups = ValidatedGroup.Update.class)
    private String userName;
}

我使用同样的方式对service使用,但是失效了。那我们相对service层使用应该怎么做呀?

怎么实现?

controller层接受字符串参数,并转换为对象



    @Autowired
    ss service;
    
@PostMapping("/getJson")
    public ResponseResult  getJson(@RequestBody String dto) {
        RequestDTO requestDTO = JSON.parseObject(dto, RequestDTO.class);
        return service.startTask(requestDTO);
    }

 service层接口

    public ResponseResult startTask(@Valid @RequestBody RequestDTO dto);

接口实现

@Validated
在当前类的头上加上  

  @Override
    public ResponseResult startTask(@Valid @RequestBody  RequestDTO dto) {
// 校验完成后的其他代码        
return start(dto);
    }

ok以上是关键的代码,下面的不关键

注意关键部分

1 service层类上加上@Validated

2 被校验的对象前加上@Valid @RequestBody(注意接口,以及接口的实现都要有)

3 在controller使用注入的方式调用即可

4 在dto里定义判断校验

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

部分dto代码

    @Length(min = 1, max = 6, message = "申请类型不合法!提示:xx")
    String approve_type;
    // xx
    Integer port_type;

    @NotNull(message = "创建人id不能为空!")
//    @Range(min = 1,message = "创建人id不能为空!")
    Long create_user_id;
    @Length(max = 32, message = "创建人名称过长!")
    String create_user_name;

全局异常处理

// 1:使用PathVariable并且是get请求的参数错误。
    // 2:使用RequestParam并且是from-data方式提交的post请求的参数错误。
    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResult handleBindGetException(ConstraintViolationException e) {
        log.error("{}", e.getMessage(), e);
        List defaultMsg = e.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
        return Params_Common_Res(defaultMsg);
    }


    // 错误情况:
    //1 使用了ResponseBody并且是json数据类型的post请求
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("{}", e.getMessage(), e);
        List defaultMsg = e.getBindingResult().getFieldErrors()
                .stream()
                .map(fieldError -> "【" + fieldError.getField() + "】" + fieldError.getDefaultMessage())
                .collect(Collectors.toList());
        return Params_Common_Res(defaultMsg);
    }

    /**
     * 兼容Validation校验框架:忽略参数异常处理器
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResult handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.error("{}", e.getMessage(), e);
        log.error("ParameterName: {}", e.getParameterName());
        log.error("ParameterType: {}", e.getParameterType());
        return Params_Common_Res();
    }

    // 前端并没有提交必要的参数信息
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResult error(HttpMessageNotReadableException e){
        log.error("{}", e.getMessage(), e);
        return ErrorResult.build(new ErrorResult( false,ErrorEnum.Params_Lack_Err.getMessage(),ErrorEnum.Params_Lack_Err.getCode()), e.getMessage());
    }

效果:

SpringBoot不在使用@Validated 做参数校验但是不想在Controller层怎么办?_第1张图片

 

你可能感兴趣的:(java,Spring,spring,boot,java,后端)