上一篇介绍了应用国际化需要考虑的问题,本篇介绍后端如何实现提示语的国际化。
?
先说说系统框架,本项目采用React + Spring + MyBatis + RabbitMQ + Redis等主流框架组合搭建而成,前后端分离。不得不说,在Spring?Framework的加持下,做什么事情都方便的多。
?
1、添加LangCookieFilter,拦截参数中带有lang的请求,并将语言标识存入cookie。
class="java" name="code">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中。另外还需配置monospace;">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";
}
}
?