上一篇介绍了应用国际化需要考虑的问题,本篇介绍后端如何实现提示语的国际化。
?
先说说系统框架,本项目采用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"; } }
?