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;
}

測試截圖

在這裏插入圖片描述

在這裏插入圖片描述

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