欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

应用国际化(2)

程序员文章站 2022-04-16 11:02:00
...

上一篇介绍了应用国际化需要考虑的问题,本篇介绍后端如何实现提示语的国际化。

 

先说说系统框架,本项目采用React + Spring + MyBatis + RabbitMQ + Redis等主流框架组合搭建而成,前后端分离。不得不说,在Spring Framework的加持下,做什么事情都方便的多。

 

1、添加LangCookieFilter,拦截参数中带有lang的请求,并将语言标识存入cookie。

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

public class LangCookieFilter implements Filter {
    // 默认参数名称
    public static final String DEFAULT_PARAM_NAME = "lang";
    
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)
			throws IOException, ServletException {
		
		HttpServletRequest request = (HttpServletRequest)arg0;
		HttpServletResponse response = (HttpServletResponse)arg1;
		
		String lang = request.getParameter(DEFAULT_PARAM_NAME);
		if(StringUtils.isNotEmpty(lang)){
			Cookie[] cookies = request.getCookies();
			boolean flag = false;
			if(cookies != null){
				for (Cookie cookie : cookies) {
					if(cookie.getName().equals(DEFAULT_PARAM_NAME)){
						cookie.setValue(lang);
						flag = true;
					}				
				}				
			}
			if(!flag){
				Cookie cookie = new Cookie(DEFAULT_PARAM_NAME, lang);
				cookie.setHttpOnly(true);
				response.addCookie(cookie);
			}			
		}
		chain.doFilter(arg0, arg1); 
	}

	@Override
	public void destroy() {}

}

 

2、配置web.xml  将LangCookieFilter添加到web.xml中。另外还需配置RequestContextListener监听,方便在MessageSourceUtils中使用

	<!-- langCookieFilter -->
	<filter>
		<filter-name>langCookieFilter</filter-name>
		<filter-class>com.rongdu.framework.core.common.cookie.LangCookieFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>langCookieFilter</filter-name>
		<url-pattern>*.htm</url-pattern>
	</filter-mapping>
	
<listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>  
</listener>

   后来看了RequestContextListener代码,感觉LangCookieFilter的做法有些多余,后续再研究。

 

3、springmvc配置文件中添加i18n支持

	  
	<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
		<property name="defaultLocale" value="zh_CN"/>
	</bean>  
	
	<!-- 国际化的消息资源文件(本系统中主要用于显示/错误消息定制) -->  
	<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
	    <property name="basenames">  
	        <list>  
	            <!-- 在web环境中一定要定位到classpath 否则默认到当前web应用下找  -->  
	            <value>classpath:i18n/message</value>  
	            <value>classpath:org/hibernate/validator/ValidationMessages</value>  
	        </list>  
	    </property>  
	    <property name="useCodeAsDefaultMessage" value="false"/>  
	    <property name="defaultEncoding" value="UTF-8"/>  
	    <property name="cacheSeconds" value="60"/>  
	</bean>

 

4、添加MessageSourceUtils工具类,获取国际化文件中国际化字段信息

import java.util.Locale;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.rongdu.framework.core.common.context.Constant;
import com.rongdu.framework.core.common.cookie.LangCookieFilter;
/**
 * 国际化语言工具类
 * @author lh@erongdu.com
 * @version 2.0
 * @since 2018-12-26
 *
 */
public class LangUtil {
	
	public static String get(){
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    	Cookie[] cookies = request.getCookies();
    	if(cookies != null){    		
	    	for (Cookie cookie : cookies) {
				if(cookie.getName().equals(LangCookieFilter.DEFAULT_PARAM_NAME)){
					return cookie.getValue();
				}
	    	}
		}
    	return Constant.DEFAULT_LANG;		
	}

	public static Locale getLocale(){
    	return new Locale(get());
    }
}

 

import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;

/**
 * 资源国际化工具类
 * @author lh@erongdu.com
 * @version 2.0
 * @since 2018-12-24
 */
@Component
public class MessageSourceUtils {

    // 日志
    private static final Logger LOGGER = LoggerFactory.getLogger(MessageSourceUtils.class);
    
    private static MessageSource messageSource;
    
    @Autowired
    public void setMessageSource(MessageSource messageSource) {
		MessageSourceUtils.messageSource = messageSource;
	}


    /**
     * 获取国际化文件中国际化字段信息
     * @param key	国际化参数
     * @param args	动态参数
     * @return
     */
    public static String getMessage(String key, Object[] args) {
    	try {
    		return messageSource.getMessage(key, args, key, LangUtil.getLocale());
    	} catch (Exception e) {
    		LOGGER.error(e.getMessage());
    	}
    	return key;
    }
    
    /**
     * 可供后台使用
     * 获取国际化文件中中文字段信息
     * @param key	国际化参数
     * @param args	动态参数
     * @return
     */
    public static String getChineseMessage(String key, Object[] args) {
    	try {
    		return messageSource.getMessage(key, args, key, Locale.CHINESE);
    	} catch (Exception e) {
    		LOGGER.error(e.getMessage());
    	}
    	return key;
    }
    
//	/**
//     * 获取国际化文件中国际化字段信息
//     * @param key	国际化key
//     * @param args	动态参数
//     * @return
//     */
//    public static String getMessage(String key, Object[] args) {
//        try {
//            Locale locale = LocaleContextHolder.getLocale();
//            return messageSource.getMessage(key, args, key, locale);
//        } catch (Exception e) {
//        	LOGGER.error(e.getMessage());
//        }
//        return key;
//    }

}

 

5、在Controller、Service等层使用MessageSourceUtils工具类

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.rongdu.framework.core.common.util.MessageSourceUtils;

@Controller
public class IndexController{

	/**
	 * 首页
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/home.htm")
	public String home(Model model){
		model.addAttribute("title", MessageSourceUtils.getMessage("title", null));
		return "home";
	}
	
}