SpringBoot is no longer using @Validated for parameter verification but what should I do if I don’t want to be at the Controller layer?

Table of contents

Scene reproduction:

How to do it?

What's the problem?

How to achieve it?


Scene reproduction:

An API interface accepts encrypted json strings. After receiving the strings, decryption is performed first. After the decryption is completed, parameter verification is required. If the parameters do not meet the specifications, a prompt message will be returned directly.

How to do it?

We can be quite satisfactory, first accept the string at the controller layer, then decrypt it, and then verify the parameters at the serivce layer, but there is a problem here, that is, the decrypted json string will become an object, and then the However, there are dozens of fields. If you use the ordinary method to check, each parameter needs an if statement, which would be terrible! ! So I consider using Validated to assist me in parameter verification.

What's the problem?

The problem is that we usually use Validated parameter verification directly at the controller layer, such as this.

    @PostMapping("/resume-info")
    public ResponseResult<String>
    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;
}

I use the same method for service, but it doesn't work. So what should we do with the service layer?

How to achieve it?

The controller layer accepts string parameters and converts them to objects



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

 service layer interface

    public ResponseResult<String> startTask(@Valid @RequestBody RequestDTO dto);

interface implementation

@Validated
在当前类的头上加上  

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

ok above is the key code, the following is not critical

Pay attention to the key part

1 Add @Validated to the service layer class

2 Add @Valid @RequestBody before the object to be verified (note that both the interface and the implementation of the interface must be present)

3 In the controller, use the injection method to call

4 Define the judgment check in dto

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

Part of dto code

    @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;

global exception handling

// 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<String> 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<String> 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());
    }

Effect:

 

Guess you like

Origin blog.csdn.net/qq_53679247/article/details/131280759