1. 程式人生 > >SpringMvc 國際化訊息處理

SpringMvc 國際化訊息處理

類似於將引數放到properties配置檔案中進行讀取,我們也可以將各種message放到配置檔案中

然後按照語言讀取不同的配置響應到頁面,從而實現國際化。

這裡我們學習messageSource的使用。

一,新增配置檔案spring-servlet-validator.xml

引入訊息配置檔案,這裡只需要寫明檔名中公共部分"message"即可

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<!-- 訊息處理,可以直接使用properties的key值,返回的是對應的value值 -->
    <bean id="messageSource"
          class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
            	<value>classpath:messages/message</value>
            </list>
        </property>
        <!-- 必須設定成false,否則hibernate原有的校驗資訊無法返回value值-->
        <property name="useCodeAsDefaultMessage" value="false"/>
    </bean>

	<!-- 它在啟動的時候會初始化hibernate validator,
	同時它引用的訊息顯示內容是前面定義的messageSource的訊息內容檔案 -->
    <bean id="myValidator"
          class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass"
                  value="org.hibernate.validator.HibernateValidator"/>
        <property name="validationMessageSource" ref="messageSource"/>
    </bean>

</beans>

二,在Spring-config.xml中引入以上配置:

<!-- Validator設定 -->
<import resource="classpath*:spring-servlet-validator.xml"/>

並且配置localeResolver bean,管理locale

<!-- 國際化訊息處理 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.FixedLocaleResolver">
	<property name="defaultLocale" value="zh_CN" />
</bean>
三,Spring-servlet.xml 中開啟掃描校驗:
	<mvc:annotation-driven validator="myValidator">
四,message配置檔案,這裡我們準備兩個,一箇中文,一個英文。放在Classpath下面。

message_zh_CN.properties

#============================= message ===============================
msg.success=\u8BBF\u95EE\u6210\u529F
valid.userInfo.userName=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A
valid.userInfo.email=\u90AE\u7BB1\u4E0D\u80FD\u4E3A\u7A7A
valid.userInfo.phone=\u7535\u8BDD\u53F7\u7801\u4E0D\u80FD\u4E3A\u5C0F\u6570
valid.userInfo.userName.notRepeat=\u7528\u6237\u540D\u5DF2\u5B58\u5728
valid.userInfo.userName.notLogin=\u7528\u6237\u540D\u5BC6\u7801\u4E0D\u6B63\u786E
message_en_US.properties
#============================= message ===============================
msg.success=success
valid.userInfo.userName=userName can not be null
valid.userInfo.email=email can not be null
valid.userInfo.phone=param phone is error
valid.userInfo.userName.notRepeat=userName already exsist
valid.userInfo.userName.notLogin=user not login

五,準備工具類,用於獲取訊息配置的內容

SpringUtils 這裡主要是要實現ApplicationContextAware,使用applicationContext.getMessage方法獲取。

package com.maven.web.util;

import java.util.Locale;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.servlet.LocaleResolver;

/**
 * Utils - Spring
 * 
 */
@Component("springUtils")
@Lazy(false)
public final class SpringUtils implements ApplicationContextAware, DisposableBean {

	/** applicationContext */
	private static ApplicationContext applicationContext;
	
	/** localeResolver */
	private static LocaleResolver localeResolver;

	/**
	 * 不可例項化
	 */
	private SpringUtils() {
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		SpringUtils.applicationContext = applicationContext;
	}

	public void destroy() throws Exception {
		applicationContext = null;
	}

	/**
	 * @return applicationContext
	 */
	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/**
	 * @param name Bean名稱
	 * @return 例項
	 */
	public static Object getBean(String name) {
		Assert.hasText(name);
		return applicationContext.getBean(name);
	}

	/**
	 * @param name Bean名稱
	 * @param type Bean型別
	 * @return 例項
	 */
	public static <T> T getBean(String name, Class<T> type) {
		Assert.hasText(name);
		Assert.notNull(type);
		return applicationContext.getBean(name, type);
	}

	/**
	 * @param code 程式碼
	 * @return 國際化訊息
	 */
	public static String getMessage(String code) {
		Locale locale = getLocaleResolver().resolveLocale(null);
		return applicationContext.getMessage(code, null, locale);
	}
	
	/**
	 * @param code 程式碼
	 * @param args 引數
	 * @return 國際化訊息
	 */
	public static String getMessage(String code, Object[] args) {
		Locale locale = getLocaleResolver().resolveLocale(null);
		return applicationContext.getMessage(code, args, locale);
	}
	
	/**
	 * @return localeResolver
	 */
	private static LocaleResolver getLocaleResolver() {
		if (localeResolver == null) {
			localeResolver = getBean("localeResolver", LocaleResolver.class);
		}
		return localeResolver;
	}

}
準備工作做好了,我們對上一篇的校驗規則進行改造。

首先是UserInfoRequest,我們在註解後面加上自定義的message

package com.maven.web.entity;

import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.Email;

import com.maven.web.validator.NotRepeat;

/**
 * 接收前端傳遞資料的對映類
 * @author Administrator
 *
 */
public class UserInfoRequest {
	
	@NotNull(message="{valid.userInfo.userName}")
	@NotRepeat
	private String userName;

	@Size(min=6, max=8)
    private String password;

	@Email
    private String email;

    /**
     * 驗證字串是否是符合指定格式的數字,interger指定整數精度,fraction指定小數精度
     */
    @Digits(integer=11,fraction=0,message="{valid.userInfo.phone}")
    private String phone;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Override
	public String toString() {
		return "UserInfoRequest [userName=" + userName + ", password=" + password + ", email=" + email + ", phone="
				+ phone + "]";
	}
    
    

}

自定義註解@NotRepeat也使用國際化訊息替代原來定義的中文訊息

package com.maven.web.validator;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target( { METHOD, FIELD, ANNOTATION_TYPE })  
@Retention(RUNTIME)  
@Constraint(validatedBy = UserNameValidator.class)  
@Documented 
public @interface NotRepeat {
	
	String message() default "{valid.userInfo.userName.notRepeat}";
	
	Class<?>[] groups() default {};  
    
    public abstract Class<? extends Payload>[] payload() default {}; 

}
在controller中我們也使用上面定義的SpringUtil獲取國際化訊息。
	/**
	 * 校驗ajax傳遞的json字串
	 * @param userInfo
	 * @return
	 */
	@RequestMapping(value="/ajax/post",method=RequestMethod.POST)
	public Result validAjax(@RequestBody @Valid UserInfoRequest userInfo){
		logger.info("如果校驗通過則列印引數:"+userInfo);
		Result r = new Result(ErrorCode.SUCCESS);
		r.setDetailMsg(SpringUtils.getMessage("msg.success"));
		return r;
	}
接下來訪問測試,http://localhost:8088/com.maven.web/valid/ajax/post


更改語音環境為英文

	<!-- 國際化訊息處理 -->
	<bean id="localeResolver" class="org.springframework.web.servlet.i18n.FixedLocaleResolver">
<!-- 		<property name="defaultLocale" value="zh_CN" /> -->
		<property name="defaultLocale" value="en_US" />
	</bean>

再次測試:



可以看到返回的提示訊息為英文。

使用freemarker也可以在頁面上使用我們定義的message,不過這是另外一篇要講述的了,有空再整理吧。