Spring Validation和Hibernate Validator結(jié)合國(guó)際化代碼實(shí)例
一、Spring Validation是什么?
日常開發(fā)中, 我們需要對(duì)請(qǐng)求參數(shù)進(jìn)行非空、長(zhǎng)度、正確性進(jìn)行校驗(yàn), 如果不使用Spring Validation,那我們會(huì)在代碼中寫很多的if來(lái)校驗(yàn), 這樣做也可以,但不優(yōu)雅, 為了優(yōu)雅的進(jìn)行入?yún)⑿r?yàn), 此時(shí)我們就需要Spring Validation.
二、項(xiàng)目說(shuō)明
1.引入依賴
依賴如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--lombok插件--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--驗(yàn)證包--> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <!--hibernate validator依賴--> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.1.6.Final</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.74</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.0-jre</version> </dependency>
2.代碼介紹
多語(yǔ)言和Spring Validation Bean初始化:
package com.zzb.valid.config;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.nio.charset.StandardCharsets;
/**
* @author create by zhouzongbo on 2020/10/27.
*/
@Configuration
public class MessageConfig implements WebMvcConfigurer {
/**
* 初始化多語(yǔ)言
* @return MessageSource
*/
@Bean
public MessageSource resourceBundleMessageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.toString());
// 多語(yǔ)言文件地址.
messageSource.addBasenames("i18n/valid");
return messageSource;
}
/**
* 本地校驗(yàn)工廠bean
* @return LocalValidatorFactoryBean
*/
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
// 設(shè)置消息源
bean.setValidationMessageSource(resourceBundleMessageSource());
return bean;
}
@Bean
public MethodValidationPostProcessor validationPostProcessor() {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
processor.setValidator(localValidatorFactoryBean().getValidator());
return processor;
}
@Override
public Validator getValidator() {
return localValidatorFactoryBean();
}
}全局異常處理代碼片段: Spring Validation 如果在校驗(yàn)時(shí)出現(xiàn)了異常, 會(huì)拋出org.springframework.web.bind.MethodArgumentNotValidException, 因此這里對(duì)MethodArgumentNotValidException進(jìn)行攔截, 然后重新組裝返回信息.
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResultEntity<?> test(MethodArgumentNotValidException ex) {
String errorMessage = buildErrorMessage(ex.getBindingResult());
return ResultEntity.failure(errorMessage);
}重新組裝異常信息
private String buildErrorMessage(BindingResult result) {
StringBuilder builder = new StringBuilder();
for (FieldError error : result.getFieldErrors()) {
final String defaultMessage = error.getDefaultMessage();
if (hasDefaultMessage(error)) {
builder.append(defaultMessage).append("\n");
} else {
// 提取錯(cuò)誤屬性值. 比如@Range 那么錯(cuò)誤屬性值包含min 和max
final Object[] arguments = error.getArguments();
Object[] args;
if (arguments == null || 1 == arguments.length) {
args = new Object[0];
} else {
args = new Object[arguments.length - 1];
System.arraycopy(arguments, 1, args, 0, args.length);
}
// 獲取錯(cuò)誤信息.
final String code = I18nUtil.getMessage(error.getCode(), args);
final String field = I18nUtil.getMessage(error.getField(), "", args);
if (StringUtils.isEmpty(field)) {
builder.append("[").append(error.getField()).append("]: ");
} else {
builder.append(field);
}
builder.append(StringUtils.isEmpty(code) ? defaultMessage : code).append("\n");
}
}
for (ObjectError globalError : result.getGlobalErrors()) {
builder.append(globalError.getDefaultMessage()).append("\n");
}
return builder.toString();
}3.自定義約束注解
用戶名長(zhǎng)度校驗(yàn)注解:
@Target(value = { ElementType.FIELD, ElementType.METHOD })
@Retention(value = RetentionPolicy.RUNTIME)
@Repeatable(UsernameLength.List.class)
@Constraint(validatedBy = UsernameLengthValidator.class) //
public @interface UsernameLength {
String message() default "{com.zzb.valid.util.validator.UsernameLength}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* 允許添加多個(gè)重復(fù)注解.
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
UsernameLength[] value();
}
}用戶名長(zhǎng)度校驗(yàn)Validator: 這里需要實(shí)現(xiàn)javax.validation.ConstraintValidator用于定義具體的校驗(yàn)規(guī)則,這里只校驗(yàn)了字符串的長(zhǎng)度.
public class UsernameLengthValidator implements ConstraintValidator<UsernameLength, String> {
public static final int MAX_LENGTH = 20;
public static final int MIN_LENGTH = 1;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return !StringUtils.isEmpty(value) && value.length() >= MIN_LENGTH && value.length() <= MAX_LENGTH;
}
}4.測(cè)試用例
從valid.properties中讀取異常提示信息,從而適配多語(yǔ)言.

4.1中文環(huán)境異常提示信息

4.2 英文環(huán)境異常提示信息.
此處與中文唯一不同的地方是把Accept-Language 設(shè)置為英文環(huán)境.

5.調(diào)用鏈
org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#resolveArgument org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor#resolveArgument org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver#validateIfApplicable org.springframework.validation.DataBinder#validate(java.lang.Object...) org.springframework.validation.DataBinder#getInternalBindingResult org.springframework.validation.beanvalidation.LocalValidatorFactoryBean # 使用個(gè)factoryBean進(jìn)行校驗(yàn). org.springframework.boot.autoconfigure.validation.ValidatorAdapter#validate(java.lang.Object, org.springframework.validation.Errors) org.springframework.validation.beanvalidation.SpringValidatorAdapter#validate(java.lang.Object, org.springframework.validation.Errors) org.springframework.validation.beanvalidation.SpringValidatorAdapter#determineField
到此這篇關(guān)于Spring Validation和Hibernate Validator結(jié)合國(guó)際化代碼實(shí)例的文章就介紹到這了,更多相關(guān)Validation和Validator結(jié)合國(guó)際化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過(guò)java備份恢復(fù)mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了如何通過(guò)java備份恢復(fù)mysql數(shù)據(jù)庫(kù),其實(shí)一般情況下通過(guò)bat或sh就可以,這里主要是介紹了java的實(shí)現(xiàn)思路,喜歡的朋友可以參考下2013-09-09
通過(guò)JWT來(lái)解決登錄認(rèn)證問題的方案
Json web token (JWT),是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)((RFC7519),該token被設(shè)計(jì)為緊湊且安全的,特別適用于分布式站點(diǎn)的單點(diǎn)登錄(SSO)場(chǎng)景,本文給大家介紹了如何通過(guò) JWT 來(lái)解決登錄認(rèn)證問題,需要的朋友可以參考下2024-12-12
Spring Cloud Gateway(讀取、修改 Request Body)的操作
這篇文章主要介紹了Spring Cloud Gateway(讀取、修改 Request Body)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
RabbitMq消息防丟失功能實(shí)現(xiàn)方式講解
這篇文章主要介紹了RabbitMq消息防丟失功能實(shí)現(xiàn),RabbitMQ中,消息丟失可以簡(jiǎn)單的分為兩種:客戶端丟失和服務(wù)端丟失。針對(duì)這兩種消息丟失,RabbitMQ都給出了相應(yīng)的解決方案2023-01-01
java刪除文件時(shí)總是返回false,刪不掉的解決方案
這篇文章主要介紹了java刪除文件時(shí)總是返回false,刪不掉的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
詳解Spring3.x 升級(jí)至 Spring4.x的方法
本篇文章主要介紹了詳解Spring3.x 升級(jí)至 Spring4.x的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
windows定時(shí)器配置執(zhí)行java jar文件的方法詳解
這篇文章主要給大家介紹了關(guān)于windows定時(shí)器配置執(zhí)行java jar文件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Java實(shí)現(xiàn)的并發(fā)任務(wù)處理實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)的并發(fā)任務(wù)處理方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了基于線程操作并發(fā)任務(wù)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Springboot結(jié)合JDBC實(shí)現(xiàn)雙數(shù)據(jù)源實(shí)例
這篇文章主要為大家介紹了Springboot結(jié)合JDBC實(shí)現(xiàn)雙數(shù)據(jù)源實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Java 發(fā)送http請(qǐng)求上傳文件功能實(shí)例
本文通過(guò)實(shí)例代碼給大家介紹了Java 發(fā)送http請(qǐng)求上傳文件功能,需要的朋友參考下吧2017-06-06

