1.引入依赖
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
</dependency>
2.定义参数校验异常拦截器
package com.example.demo.exception.global;
import com.alibaba.cola.dto.SingleResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler({ConstraintViolationException.class,
MethodArgumentNotValidException.class,
ServletRequestBindingException.class,
BindException.class})
public SingleResponse<Object> handleValidationException(Exception e) {
String msg;
if (e instanceof MethodArgumentNotValidException) {
MethodArgumentNotValidException t = (MethodArgumentNotValidException) e;
msg = getBindingResultMsg(t.getBindingResult());
} else if (e instanceof BindException) {
BindException t = (BindException) e;
msg = getBindingResultMsg(t.getBindingResult());
} else if (e instanceof ConstraintViolationException) {
ConstraintViolationException t = (ConstraintViolationException) e;
msg = t.getConstraintViolations().stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(","));
} else if (e instanceof MissingServletRequestParameterException) {
MissingServletRequestParameterException t = (MissingServletRequestParameterException) e;
msg = t.getParameterName() + " 不能为空";
} else if (e instanceof MissingPathVariableException) {
MissingPathVariableException t = (MissingPathVariableException) e;
msg = t.getVariableName() + " 不能为空";
} else {
msg = "必填参数缺失";
}
return SingleResponse.buildFailure(String.valueOf(ErrorCode.PARAMETER_ERROR.getCode()), msg);
}
private String getBindingResultMsg(BindingResult bindingResult) {
StringBuilder stringBuilder = new StringBuilder();
if (bindingResult.hasErrors()) {
for (ObjectError error : bindingResult.getAllErrors()) {
stringBuilder.append(error.getDefaultMessage()).append(";");
}
}
return stringBuilder.toString();
}
}
这里推荐一个常用的api包
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-dto</artifactId>
<version>4.0.1</version>
</dependency>
3.校验参数
package com.example.api.domain.message.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.List;
/**
* com.avatar.socketio.server.domain.message.dto
* Description:
* 发送消息参数
*
* @author jack
* @date 2021/06/24 5:31 下午
*/
@Data
public class MessageDTO implements Serializable {
private static final long serialVersionUID = -4201486472018401037L;
/**
* 消息内容
*/
@NotBlank
private String content;
/**
* 发送方
*/
private String sender;
/**
* 接收方
*/
@NotEmpty(message = "接收方不能为空")
private List<String> receiverList;
/**
* 命名空间
*/
@NotBlank(message = "命名空间不能为空")
private String namespace;
}
4.测试
package com.example.controller.message;
import com.alibaba.cola.dto.SingleResponse;
import com.avatar.api.common.response.PlainResult;
import com.avatar.api.common.utils.ResultUtils;
import com.avatar.socketio.api.domain.message.dto.BroadCastMessageDTO;
import com.avatar.socketio.api.domain.message.dto.MessageDTO;
import com.avatar.socketio.server.service.message.MessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@RestController
@RequestMapping("/api/v1/message")
@Slf4j
@RequiredArgsConstructor
public class MessageController {
@PostMapping("/addMessage")
public SingleResponse<Object> addMessage(@RequestBody @Validated MessageDTO messageDTO) {
log.info("messageDTO:{}",messageDTO);
return SingleResponse.of(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
}
5. @Validated和@Valid的区别
@Validated:用在方法入参上无法单独提供嵌套验证功能。不能用在成员属性(字段)上,也无法提示框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。
@Valid:用在方法入参上无法单独提供嵌套验证功能。能够用在成员属性(字段)上,提示验证框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。