SpringMVC国际化i18n配置

国际化是什么?

国际化是开发支持多语言和数据格式的技术。其实就是根据外部特征动态的将本地化资源响应给用户。

本地化资源配置文件

SpringMVC中实现国际化,是将每一个地区的语言保存在配置文件中,配置的内容是key/value对,key是字符串,value可以是字符串,也可以是其他任意类型的对象。
一个配置文件表示一种语言,如果要同时支持中文和英文,那么就需要提供两个属性文件,并且中英文内容相同的value,要对应相同的key
配置文件的命名是:basename_languageCode_countryCode.properties,例如默认文件messages.properties,中文的messages_zh_CN.properties。当根据languageCode获取不到配置文件时,就会使用默认的配置文件
汉语的配置文件,要将汉字转换成Unicode,创建文件分两步:

  1. 随意创建文本文件
  2. 将文本文件的内容转换成unicode表示

idea中创建如下,注意,messages_en_US.properties中的US实际上可以去掉,通常情况下是去掉的;Resource Bundle 'messages'不是文件夹,当生成配置文件后就出现了这个,实际表示的是messagesbasename
在这里插入图片描述

如果idea中的中文已经是unicode,但是想看中文
在这里插入图片描述

SpringMVC配置

  1. 注解驱动

    <mvc:annotation-driven validator="validator" />
    
  2. 加载国际化资源文件

    <bean id="messageSource"
       class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
     <!-- 指定配置文件路径及basename -->
    	<property name="basename" value="classpath:config/i18n/messages" />
    	<property name="fileEncodings" value="utf-8" />
    	<!-- 缓存120s,可以动态加载messages.properties中的数据(修改文件数据,不需要重启) -->
    	<property name="cacheSeconds" value="120" />
    </bean>
    
  3. 加载校验器,需要注入到注解驱动中

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    	<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
    	<property name="validationMessageSource" ref="messageSource" />
    </bean>
    
  4. 加载国际化语言区域解析器:浏览器语言解析器

    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" />
    
  5. 语言区域更改拦截器,测试验证时,发现不配置也可以

    <mvc:interceptors>
       <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
    </mvc:interceptors>
    

测试代码

// 校验工具类
public class ValidatorUtils {
    private static final Logger logger = LoggerFactory.getLogger(ValidatorUtils.class);
    public static void beanValid(BindingResult bindingResult, LocaleService localeService) {
        if (bindingResult.hasErrors()) {
            StringBuilder joinMessage = new StringBuilder();
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError objectError : allErrors) {
                joinMessage.append(",").append(localeService.getMessage(objectError.getDefaultMessage()));
            }
            if (joinMessage.length() > 0) {
                String message = joinMessage.deleteCharAt(0).toString();
                logger.info("i18n message:" + message);
                throw new RequestParamException(message);
            }
        }
    }
}

// 从messages中替换显示内容
@Component
public class LocaleService {
    @Autowired
    private MessageSource messageSource;
    public String getMessage(String code) {
        Locale locale = LocaleContextHolder.getLocale();
        String message = messageSource.getMessage(code, new Object[]{}, locale);
        if (StringUtils.isNotBlank(message)) {
            return message;
        }
        return code;
    }
}

// 异常
@RestControllerAdvice
public class ExceptionHandle {
    @ExceptionHandler(RequestParamException.class)
    public Object handleRequestParamException(RequestParamException e) {
        Map result = new HashMap();
        result.put("code", 200);
        result.put("message", e.getMsg());
        return result;
    }
}

public class RequestParamException extends RuntimeException{
    public RequestParamException(String msg) {
        this.msg = msg;
    }
    private String msg;
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

// 测试接口及实体
@RestController
@RequestMapping("/bindingResult")
public class BindingResultController {

    @Resource
    private LocaleService localeService;

    @RequestMapping("/test")
    public Object test(@Valid Person person, BindingResult result) {
        ValidatorUtils.beanValid(result, localeService);
        return new Object();
    }
}
// 省略了set和get方法
public class Person implements Serializable {
   @NotNull(message = "person.name_is_null")
   private String name;
   @NotNull(message = "person.age_is_null")
   @Range(min = 1, max = 200, message = "person.age_is_illegal")
   private Integer age;
}

测试截图

在这里插入图片描述

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章