SpringBoot参数校验进阶:自定义注解+国际化错误提示

🎓博主介绍: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 中实现更灵活、更友好的参数校验功能。自定义注解可以满足复杂的业务校验需求,而国际化错误提示则可以提升不同语言用户的使用体验。在实际开发中,我们可以根据具体的业务场景定义更多的自定义注解,并根据不同的语言环境提供相应的错误提示信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fanxbl957

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值