Table of contents
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: