很多项目需要国际化配置,即后端接口返回的参数是不同的语言,依据前端请求的参数判断,有放到参数里URL后面(......?lang=zh_CN)、有放到请求头header里(accept-language = zh-CN)等等。开发过程中,参数校验必不可少,当然校验的方式有很多,之前用过缺少哪个参数,直接抛异常,然后交给全局异常处理器给出,不方便;基于注解的方式读取配置文件,还能国际化,这样更加优雅,提高代码的可维护性;今天我们首先分享标识放到URL后面这种情况:
一、框架默认的国际化配置:
1、实现 LocaleResolver 中的接口:
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
/**
* URL上带上国家标识信息
* @author wanghuainan
* @date 2020/10/15
*/
public class NanDaoLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
/**
* 取国家标识参数
* http://localhost:8080/api/validate2?lang=zh_CN
*/
String l = httpServletRequest.getParameter("lang");
Locale locale = Locale.getDefault();
if (!StringUtils.isEmpty(l)) {
String[] split = l.split("_");
locale = new Locale(split[0], split[1]);//把标识参数放到local里面
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
2、把取到国家标识的配置放到springBoot容器里:
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
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.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
/**
* @author wanghuainan
* @date 2021/10/13
* 在URL后面加参数,需要此类 ?lang=zh_CN/?lang=zh_US;
* 如果后端通过请求头接参数:accept-language:zh-CN/en ,则需要注释调此类;即上下是互斥的
*/
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class LocaleConfig extends WebMvcConfigurerAdapter{
/*@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
// 默认语言
slr.setDefaultLocale(Locale.CHINA);
return slr;
}*/
/**
* 引入自定义Local(通过浏览器传标识:http://localhost:8080/api/validate2?lang=zh_CN)
* @return
*/
@Bean
public LocaleResolver localeResolver() {
return new NanDaoLocaleResolver();
}
/*@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver slr = new CookieLocaleResolver();
// 默认语言
slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return slr;
}*/
/* @Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
// 参数名
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
super.addInterceptors(registry);
}*/
}
3、测试的接口:
/**
* http://localhost:8888/api/validate2?lang=en_US
* http://localhost:8888/api/validate2?lang=zh_CN
* @param user
* @return
*/
@PostMapping("/validate2")
@ResponseBody
public String validate(@Valid @RequestBody UserInfo user) {
return null;
}
4、相应的VO
import lombok.Data;
import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.constraints.Size;
/**
* @author wanghuainan
* @date 2021/10/15
*/
@Data
public class UserInfo {
//@Size(min = 1, max = 10, message = "姓名长度必须为1到10")
// @NotEmpty(message = "{user.name.notBlank}")
//@NotEmpty(message = "{demo.key.null}")//必须配置地址:basename: static/i18n/messages
@NotEmpty()//此时默认框架中的国际化语言,即此处不需要加message
private String name;
}
5、启动后用 postman
5.1、英文请求:http://localhost:8080/api/validate2?lang=en_US
结果:
5.2、中文请求:http://localhost:8080/api/validate2?lang=zh_CN
结果:
5.3、韩语请求:http://localhost:8080/api/validate2?lang=ko_KP
框架中默认的国际化语言应该有多种 ,大家可以根据需要选择传参;
另外特别注意:控制层的接口上必须加上 @Valid /@Validated 中的一个注解
VO或者接口上的注解一定要用官方提供的,自定义的无效!
二、自定义国际化配置文件:
1、在resources 目录下创建配置文件:
2、yml配置中添加配置:
spring:
thymeleaf:
encoding=UTF-8
content-type=text/html
cache=false
mode=LEGACYHTML5
messages:
encoding: UTF-8
cache-seconds: 1
basename: static/i18n/messages
3、VO中的处理:控制层的接不变
/**
* @author wanghuainan
* @date 2021/10/15
*/
@Data
public class UserInfo {
//@Size(min = 1, max = 10, message = "姓名长度必须为1到10")
// @NotEmpty(message = "{user.name.notBlank}")
@NotEmpty(message = "{demo.key.null}")//必须配置地址:basename: static/i18n/messages
//@NotEmpty()
private String name;
}
4、properties配置文件里添加:
英文配置:
5、重写springbot校验类:WebMvcConfigurationSupport
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @author wanghuainan
* @date 2021/10/13
* 在URL后面加参数,并且使用默认国际化校验时不需要此类 (如果自定义国际化配置文件一定需要此类)?lang=zh_CN/?lang=zh_US;
* 如果后端通过请求头接参数:accept-language:zh-CN/en ,则需要调此类;即上下是互斥的
*/
@Configuration
public class ValidatorConfiguration extends WebMvcConfigurationSupport {
@Autowired
private MessageSource messageSource;
@Override
public Validator getValidator() {
return validator();
}
@Bean
public Validator validator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource);
return validator;
}
}
5、启动后请求:
5.1、中文:http://localhost:8080/api/validate2?lang=zh_CN
5.2、英文:http://localhost:8080/api/validate2?lang=en_US
到此,请求参数访问的方式,分享完毕,大家多测试会更清晰,下篇分享 请求头传标识的方式,敬请期待!