1.pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.配置快速失败模式
package gen.controller;
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator;
import org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
@Configuration
public class ValidatorConfiguration {
@Bean
public Validator validator() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("ValidationMessages");
MessageSourceResourceBundleLocator bundleLocator = new MessageSourceResourceBundleLocator(messageSource);
ResourceBundleMessageInterpolator messageInterpolator = new ResourceBundleMessageInterpolator(bundleLocator);
LocaleContextMessageInterpolator localeMessageInterpolator = new LocaleContextMessageInterpolator(messageInterpolator);
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
// 快速失败模式
.failFast(true)
.messageInterpolator(localeMessageInterpolator)
.buildValidatorFactory();
return validatorFactory.getValidator();
}
}
3.配置国际化文件
ValidationMessages.properties
customer.countryName.NotBlank=countryName不能为空
customer.countryCode.NotNull=countryCode不能为空
customerCode.NotBlank=用户编码不可以为空!
customerName.NotBlank=用户名称不能为空!
ValidationMessages_zh.properties
customer.countryName.NotBlank=countryName不能为空
customer.countryCode.NotNull=countryCode不能为空
customerCode.NotBlank=用户编码不可以为空!
customerName.NotBlank=用户名称不能为空!
ValidationMessages_en.properties
customer.countryName.NotBlank=countryName is required
customer.countryCode.NotNull=countryCode is required
customerCode.NotBlank=customerCode cannot be empty
customerName.NotBlank=customerName cannot be empty
4.配置校验异常拦截
package gen.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
public RtnMsg handleViolationException(Exception e) {
log.error("handleViolationException has occurred", e);
RtnMsg rtnMsg = RtnMsg.builder().code(-1).build();
String msg = null;
if (e instanceof MethodArgumentNotValidException) {
BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
// getFieldError获取的是第一个不合法的参数
FieldError fieldError = bindingResult.getFieldError();
if (fieldError != null) {
msg = fieldError.getDefaultMessage();
}
} else if (e instanceof BindException) {
// getFieldError获取的是第一个不合法的参数
FieldError fieldError = ((BindException) e).getFieldError();
if (fieldError != null) {
msg = fieldError.getDefaultMessage();
}
} else if (e instanceof ConstraintViolationException) {
msg = e.getMessage();
if (msg != null) {
int lastIndex = msg.lastIndexOf(':');
if (lastIndex >= 0) {
msg = msg.substring(lastIndex + 1).trim();
}
}
/// ValidationException 的其它子类异常
} else {
msg = "处理参数时异常";
}
rtnMsg.setMsg(msg);
return rtnMsg;
}
}
package gen.controller;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RtnMsg {
private int code;
private String msg;
private Object data;
}
5.定义Controller和Dto
package gen.controller;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class CustomerDto {
private Long id;
@NotBlank(message = "{customer.countryName.NotBlank}")
private String countryName;
@NotNull(message = "{customer.countryCode.NotNull}")
private String countryCode;
@Email
private String email;
}
package gen.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.NotBlank;
@RestController
@Slf4j
@Validated
public class IndexController {
@GetMapping("/get")
public String get(@NotBlank(message = "{customerCode.NotBlank}") String customerCode
, @NotBlank(message = "{customerName.NotBlank}") String customerName) {
log.info(customerCode);
log.info(customerName);
return "success";
}
@PostMapping("/post")
public String post(@RequestBody @Validated CustomerDto customerDto) {
log.info(customerDto.toString());
return "success";
}
}
6.发起请求,通过Accept-Language请求头完成国际化切换