🎓博主介绍:Java、Python、js全栈开发 “多面手”,精通多种编程语言和技术,痴迷于人工智能领域。秉持着对技术的热爱与执着,持续探索创新,愿在此分享交流和学习,与大家共进步。
📖DeepSeek-行业融合之万象视界(附实战案例详解100+)
📖全栈开发环境搭建运行攻略:多语言一站式指南(环境搭建+运行+调试+发布+保姆级详解)
👉感兴趣的可以先收藏起来,希望帮助更多的人
SpringBoot 参数校验进阶:自定义注解+国际化错误提示
一、引言
在 Spring Boot 开发中,参数校验是一个常见且重要的功能。它可以帮助我们确保传入的数据符合业务规则,提高系统的稳定性和安全性。Spring Boot 提供了 @Valid、@NotNull、@NotEmpty 等一系列内置注解来进行基本的参数校验,但在实际业务场景中,这些内置注解可能无法满足复杂的校验需求。此时,我们可以通过自定义注解的方式来实现更灵活的参数校验。同时,为了提升用户体验,我们还可以结合国际化配置,根据不同的语言环境给出相应的错误提示信息。本文将详细介绍如何在 Spring Boot 中实现自定义注解的参数校验以及国际化错误提示。
二、Spring Boot 基础参数校验回顾
2.1 引入依赖
在 pom.xml 中引入 Spring Boot Starter Validation 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.2 使用内置注解进行参数校验
以下是一个简单的示例,演示如何使用内置注解对实体类的属性进行校验:
import javax.validation.constraints.NotBlank;
public class User {
@NotBlank(message = "用户名不能为空")
private String username;
// getter 和 setter 方法
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
在控制器中使用 @Valid 注解触发校验:
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
public class UserController {
@PostMapping("/users")
public String createUser(@Valid @RequestBody User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return bindingResult.getFieldError().getDefaultMessage();
}
return "用户创建成功";
}
}
三、自定义注解实现参数校验
3.1 定义自定义注解
假设我们需要校验一个字符串是否为特定格式的手机号码,我们可以定义一个自定义注解 @Phone:
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Constraint(validatedBy = PhoneValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Phone {
String message() default "手机号码格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
3.2 实现校验器
创建一个实现 ConstraintValidator 接口的校验器类 PhoneValidator:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
public class PhoneValidator implements ConstraintValidator<Phone, String> {
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
@Override
public void initialize(Phone constraintAnnotation) {
// 初始化方法,可用于获取注解中的属性值
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return PHONE_PATTERN.matcher(value).matches();
}
}
3.3 使用自定义注解
在实体类中使用自定义注解:
import javax.validation.constraints.NotBlank;
public class User {
@NotBlank(message = "用户名不能为空")
private String username;
@Phone(message = "手机号码格式不正确")
private String phone;
// getter 和 setter 方法
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
四、国际化错误提示配置
4.1 配置国际化资源文件
在 src/main/resources 目录下创建 i18n 文件夹,并在该文件夹下创建 messages.properties(默认语言)、messages_en_US.properties(英文)和 messages_zh_CN.properties(中文)三个文件。
messages.properties:
user.username.notblank=用户名不能为空
user.phone.invalid=手机号码格式不正确
messages_en_US.properties:
user.username.notblank=Username cannot be empty
user.phone.invalid=Invalid phone number format
messages_zh_CN.properties:
user.username.notblank=用户名不能为空
user.phone.invalid=手机号码格式不正确
4.2 配置国际化解析器
在配置类中配置国际化解析器:
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.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.US);
return slr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("i18n/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
factoryBean.setValidationMessageSource(messageSource());
return factoryBean;
}
}
4.3 修改自定义注解的错误消息
将自定义注解 @Phone 的错误消息改为国际化资源文件中的键:
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Constraint(validatedBy = PhoneValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Phone {
String message() default "{user.phone.invalid}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
4.4 测试国际化错误提示
在请求 URL 中添加 lang 参数来指定语言环境,例如:
http://localhost:8080/users?lang=en_US
五、总结
通过自定义注解和国际化错误提示,我们可以在 Spring Boot 中实现更灵活、更友好的参数校验功能。自定义注解可以满足复杂的业务校验需求,而国际化错误提示则可以提升不同语言用户的使用体验。在实际开发中,我们可以根据具体的业务场景定义更多的自定义注解,并根据不同的语言环境提供相应的错误提示信息。

1732

被折叠的 条评论
为什么被折叠?



