参数校验提示语国际化(language由参数给定)
创建国际化资源文件:在 src/main/resources 下创建 i18n 文件夹,并在其中创建语言文件,例如 messages.properties 和 messages_zh.properties
# messages.properties (default English)
sms.logId.notNull=Log ID cannot be null
sms.mobile.notNull=Mobile number cannot be null
sms.channelId.notNull=Channel ID cannot be null
sms.apiTemplateId.notNull=API Template ID cannot be null
# messages_zh.properties (Chinese)
sms.logId.notNull=短信日志编号不能为空
sms.mobile.notNull=手机号不能为空
sms.channelId.notNull=短信渠道编号不能为空
sms.apiTemplateId.notNull=短信 API 的模板编号不能为空
配置国际化支持:在 Spring Boot 中配置国际化支持,包括 MessageSource 和 LocaleResolver
@Configuration
public class InternationalizationConfig {
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("i18n/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
在 SmsSendMessage 类中使用国际化消息:修改 SmsSendMessage 类,使用 @NotNull 注解的 message 属性来引用国际化消息。
import javax.validation.constraints.NotNull;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.MessageSource;
import org.springframework.beans.factory.annotation.Autowired;
@Data
public class SmsSendMessage {
@NotNull(message = "{sms.logId.notNull}")
private Long logId;
@NotNull(message = "{sms.mobile.notNull}")
private String mobile;
@NotNull(message = "{sms.channelId.notNull}")
private Long channelId;
@NotNull(message = "{sms.apiTemplateId.notNull}")
private String apiTemplateId;
private List<KeyValue<String, Object>> templateParams;
}
在控制器中获取语言参数并设置 Locale:在需要的地方获取 Headers 中的语言参数,并设置 Locale。
@RestController
@RequestMapping("/sms")
public class SmsController {
@Autowired
private MessageSource messageSource;
@PostMapping("/send")
public ResponseEntity<String> sendSms(@RequestHeader(value = "Accept-Language", defaultValue = "en") String lang, @Valid @RequestBody SmsSendMessage message) {
LocaleContextHolder.setLocale(Locale.forLanguageTag(lang));
// Your logic to send SMS
return ResponseEntity.ok("SMS sent successfully");
}
}
自定义异常类提示语, language从Headers的Accept-Language中获取:
1. 配置 MessageSource 以支持国际化
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;
@Configuration
public class ValidationConfig {
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public LocalValidatorFactoryBean getValidator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
}
2. 配置国际化拦截器
配置 LocaleChangeInterceptor 和 LocaleResolver 以从头部获取语言信息:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import java.util.Locale;
@Configuration
public class LocaleConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
return resolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("Accept-Language");
return interceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
3. 定义自定义异常
定义一个自定义异常类,用于携带国际化消息的键和参数:
public class CustomException extends RuntimeException {
private final String messageKey;
private final Object[] args;
public CustomException(String messageKey, Object... args) {
super(messageKey);
this.messageKey = messageKey;
this.args = args;
}
public String getMessageKey() {
return messageKey;
}
public Object[] getArgs() {
return args;
}
}
4. 创建异常处理器
使用 @ControllerAdvice 创建全局异常处理器,以捕获异常并返回国际化的错误消息:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import java.util.Locale;
@ControllerAdvice
public class GlobalExceptionHandler {
@Autowired
private MessageSource messageSource;
@ExceptionHandler(CustomException.class)
public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex, WebRequest request) {
Locale locale = request.getLocale();
String message = messageSource.getMessage(ex.getMessageKey(), ex.getArgs(), locale);
ErrorResponse errorResponse = new ErrorResponse(HttpStatus.BAD_REQUEST.value(), message);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
// 其他异常处理方法
}
5. 定义错误响应类
定义一个类来表示错误响应:
public class ErrorResponse {
private int status;
private String message;
public ErrorResponse(int status, String message) {
this.status = status;
this.message = message;
}
// getters and setters
}
6. 抛出自定义异常
在你的业务逻辑中,遇到错误时抛出 CustomException:
import org.springframework.stereotype.Service;
@Service
public class SmsService {
public void sendSms(SmsSendMessage smsSendMessage) {
if (smsSendMessage.getMobile() == null) {
throw new CustomException("sms.mobile.notNull");
}
// 其他逻辑
}
}