自定义 i18n国际化

自定义 i18n国际化

java服务器代码

本逻辑是为每一个httpsesion创建一个i18n对象,和用户登录无关

新建Tag标签类 I18nTag.java
import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

import org.apache.commons.lang3.StringUtils;

public class I18nTag extends SimpleTagSupport{
	
	private String value;

	@Override
	public void doTag() throws JspException, IOException{
		PageContext pageContext=(PageContext) super.getJspContext();
		HttpSession session=pageContext.getSession();
		
		@SuppressWarnings("unchecked")
		Map<String,String> i18nMap=(Map<String, String>) session.getAttribute("i18n");
		String result=getValue();
		if(StringUtils.isBlank(result)) {
			result="";
		}else {
			result=i18nMap.get(getValue());
			if(StringUtils.isBlank(result)) {
				result="";
			}
		}
		pageContext.getOut().write(result);
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}	
}
新建i18n.tld文件

tld文件需要放在WEB-INF 下面

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
	<tlib-version>1.0</tlib-version>
	<jsp-version>2.0</jsp-version>
	<short-name>i18n</short-name>
	<uri>http://java.sun.com/i18n</uri>
	<tag>
		<name>i18n</name>
		<tagclass>com.shine.pb.taglib.I18nTag</tagclass>
		<info>i18n</info>
		<body-content>empty</body-content>
		<attribute>
            <name>value</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
            <description>文档加载完毕了再执行脚本</description>
        </attribute>
	</tag>
</taglib>

新建i18n过滤器 I18nFilter.java
import java.io.IOException;
import java.util.Map;

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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;

import com.util.I18nUtils;

public class I18nFilter implements Filter {

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse rsp, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) rsp;
		String url = request.getRequestURI();
		if (!(StringUtils.isNotBlank(url) && url.indexOf("i18nSet") > -1)) {
			HttpSession session = request.getSession();
			String i18nType = (String) session.getAttribute(I18nUtils.i18nType);
			if (StringUtils.isBlank(i18nType) || !I18nObject.getLocaleType(session).equals(i18nType)) {
				session.removeAttribute(I18nUtils.i18n);
				session.removeAttribute(I18nUtils.i18nType);
				I18nObject i18nObject = new I18nObject();
				I18nObject.setLocaleType(session, i18nType);
				Map<String, String> map = i18nObject.getShowDatas(session);
				session.setAttribute(I18nUtils.i18n, map);
				i18nType = StringUtils.isBlank(i18nType) ? I18nUtils.zh_CN : i18nType;
				session.setAttribute(I18nUtils.i18nType, i18nType);
			}
		}
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {

	}

}

新建设置i18n参数的servlet,I18nSetTypeServlet.java
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.util.I18nUtils;

/**
 * 设置i18n的参数
 * @author callens
 *
 */
public class I18nSetTypeServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = -6378531597637970751L;
	
	private Logger log = LoggerFactory.getLogger(I18nSetTypeServlet.class);

	@Override
	protected void doGet(HttpServletRequest rerquest, HttpServletResponse response) throws ServletException, IOException {
		String i18nType=(String) rerquest.getParameter(I18nUtils.i18nType);
		if(StringUtils.isBlank(i18nType)) {
		}
		if(StringUtils.isNotBlank(i18nType)&&(I18nUtils.zh_CN.equals(i18nType)||I18nUtils.en_US.equals(i18nType))) {
			HttpSession session=rerquest.getSession();
			session.setAttribute(I18nUtils.i18nType, i18nType);
		}else {
			log.error("i18nType param is error,i18nType value is {}",i18nType);
		}
	}
}

在web.xml里面配置
<filter><!-- 写入i18n -->
    <filter-name>i18nFilter</filter-name>
    <filter-class>com.filter.i18n.I18nFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>i18nFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
    <servlet-name>i18nSet</servlet-name>
    <servlet-class>com.filter.i18n.I18nSetTypeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>i18nSet</servlet-name>
    <url-pattern>/i18nSet</url-pattern>
  </servlet-mapping>
新建i18n参数类,I18nUtils.java
package com.util;

public class I18nUtils {
	
	public static final String i18nType="i18nType";
	
	public static final String zh_CN="zh_CN";
	
	public static final String en_US="en_US";
	
	public static final String i18n="i18n";
}

创建i18存储的内存环境,I18nSingle.java
package com.filter.i18n;

import java.util.Map;
import java.util.WeakHashMap;

import javax.servlet.http.HttpSession;

/**
 * why 为什么会出现这个类呢
 * 是因为i18n的存储条件为httpSession范围
 * 使用其单例模式,避免出现多对象
 * 其存储了一个map对象,该map对象保存每个httpsession对应的i18n的类型
 * 按理说也可以使用缓存技术的,但还是需要删除缓存,这个时间应该和session时间过期一致
 * //map对象使用弱引用,省去了删除key键的操作
 * //为何使用弱引用,是因为不知道httpSession何时销毁,这个销毁操作应该是tomcat容器进行控制的
 *  //如果使用tomcat容器的代码,势必会嵌入更多的逻辑,为其减少代码的逻辑量,在此处使用弱引用
 *  //何为弱引用,但key值没用对应的对象引用,则弱引用map会在gc回收的时候进行销毁此键值对
 * @author callens
 *
 */
public class I18nSingle {
	
	private Map<HttpSession, String> map = new WeakHashMap<>();
	
	// 使用volatile 保证其可见性,在多并发中保证其原子性
	volatile private static I18nSingle i18nSingle = null;

	public static I18nSingle getInstance() {
		try {
			if (i18nSingle != null) {

			} else {
				synchronized (I18nSingle.class) {
					if (i18nSingle == null) {
						i18nSingle = new I18nSingle();
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return i18nSingle;
	}

	public String getLocaleType(HttpSession session) {
		return map.get(session);
	}

	public void setLocaleType(HttpSession session,String localeType) {
		map.put(session, localeType);
	}
	
}

读取i18n的配置对象,I18nProperties.java
package com.filter.i18n;

import java.util.Locale;
import java.util.ResourceBundle;

/**
 * 读取i18n的配置文件
 * @author callens
 *
 */
public class I18nProperties {
	
	public ResourceBundle getLocale() {
		Locale locale=new Locale("zh", "cn");//设置语言环境
		ResourceBundle resource = ResourceBundle.getBundle("i18n",locale);
		return resource;
	}
	
	public ResourceBundle getLocaleUS() {
		Locale locale=new Locale("en", "US");//设置语言环境
		ResourceBundle resource = ResourceBundle.getBundle("i18n",locale);
		return resource;
	}
}

创建i18n对象,I18nObject.java
package com.filter.i18n;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;

import com.util.I18nUtils;

/**
 * 创建i18n对象
 * @author callens
 *
 */
public class I18nObject {
	
	private I18nProperties properties=new I18nProperties();

	public Map<String,String> getShowDatas(HttpSession session){
		Map<String,String> datas=new HashMap<>();
		ResourceBundle resource=getResource(session);
		Enumeration<String> enumeration=resource.getKeys();
		String key;
		while(enumeration.hasMoreElements()) {
			key=enumeration.nextElement();
			datas.put(key, resource.getString(key));
		}
		return datas;
	}
	
	/**
	 * 获取配置文件
	 * @return
	 */
	private ResourceBundle getResource(HttpSession session) {
		ResourceBundle resource;
		String localeType=getLocaleType(session);
		if(StringUtils.isNotBlank(localeType)) {
			if(I18nUtils.zh_CN.equals(localeType)) {
				resource=properties.getLocale();
			}else {
				resource=properties.getLocaleUS();
			}
		}else {
			resource=properties.getLocale();
		}
		return resource;
	}

	public static String getLocaleType(HttpSession session) {
		String localeType=I18nSingle.getInstance().getLocaleType(session);
		return StringUtils.isBlank(localeType)?I18nUtils.zh_CN:localeType;
	}
	
	public static void setLocaleType(HttpSession session,String i18nType) {
		I18nSingle.getInstance().setLocaleType(session, i18nType);
	}
}

web 页面代码

切换中英文页面代码
<div class="nice-select" name="nice-select">
  <input type="text" id="i18nValue" value="" readonly="readonly" />
  <ul>
      <li class="on"></li>
      <li>English</li>
    </ul>
</div>
i18页面样式
/*下拉框 start*/
.nice-select {
	float:right;
    width: 35px;
    background: url(../images/wl2.png) 28px 10px no-repeat;
    height: 24px;
    line-height: 24px;
    text-align: left;
    position: relative;
    cursor: pointer;
    box-sizing: content-box;
    padding-top: 9px;
    margin-right: -10px;
    margin-left: 10px;
}
.nice-select:hover{ 
	background-position: 28px -14px;
}
.nice-select.on{
    background-position: 28px -35px;
}
.nice-select input {
    display: block;
    width: 50px;
    height: 24px;
    line-height: 24px;
    border: 0;
    outline: 0;
    background: none;
    color: #999;
    cursor: pointer;
    text-align: center;
}
.nice-select ul {
    width: 50px;
    display: none;
    position: absolute;
    left: 0;
    top: 26px;
    overflow: hidden;
    background-color: #fff;
    z-index: 4;
    border-radius: 3px;
    box-shadow: 0 4px 10px rgba(0,0,0,0.1);
    border: 1px solid #efefef;
    top: 35px;
}
.nice-select ul li {
    height: 32px;
    line-height: 32px;
    font-size: 12px;
    color: #666;
    overflow: hidden;
    text-align: center;
    cursor: pointer;
    text-align: center;
}
.nice-select ul li:hover{ 
	background: #fce8e9;
}
.nice-select ul .on,.nice-select ul li.on:hover { 
	cursor: default; 
	background-color: #fafafa; 
	color: #ccc;
}

i18n JS代码
$(document).ready(function(){
	bindClick();
	initI18n();
});
function bindClick(){
	$('[name="nice-select"]').click(function(e) {
		$('[name="nice-select"]').find('ul').hide();
		$(this).find('ul').show();
		$(this).addClass("on").siblings('[name="nice-select"]').removeClass("on")
		e.stopPropagation(); //阻止冒泡事件
	});
	
	$('[name="nice-select"] li').click(function(e) {
		$(this).addClass("on").siblings().removeClass("on");
		$(this).parents('[name="nice-select"]').removeClass("on");
		var val = $(this).text();
		$(this).parents('[name="nice-select"]').find('input').val(val);
		$('[name="nice-select"] ul').hide();
		e.stopPropagation();
		setI18nType(val);
	});
	
	$(document).click(function() {
 		$('[name="nice-select"]').removeClass("on")
 		$('[name="nice-select"] ul').hide();
 	});
}
function initI18n(){
	if(i18nType!=""){
		let i18nTypeValue="中";
		if(i18nType=="en_US"){
			i18nTypeValue="English";
		}
		$("#i18nValue").val(i18nTypeValue);
		$('[name="nice-select"] li').each(function(i,value){
			let i18Value=$(value).text();
			if(i18Value==i18nTypeValue){
				$(value).addClass("on").siblings().removeClass("on");
				$(value).parents('[name="nice-select"]').removeClass("on");
				$(value).parents('[name="nice-select"]').find('input').val(i18Value);
			}
		});
	}
}
function setI18nType(value){
	let i18nTypeValue="zh_CN";
	if(value=="English"){
		i18nTypeValue="en_US";
	}
	let url="/i18nSet?i18nType="+i18nTypeValue;
	$.ajax({
		type:"GET",
		url:url,
		success:function(result){
			window.location.reload();
		},
		error:function(e){
			console.log(e);
		}
	});
}

i18n在页面上如何进行使用

<!-- 引入标签 -->
<%@ taglib uri="http://java.sun.com/i18n" prefix="i18n" %><!-- prefix可以进行自定义 -->
<!-- 引入css -->
<link rel="stylesheet" href="i18n.css" />
<!-- 引入js -->
<script src="i18n.js" type="text/javascript"></script>


<script type="text/javascript">
    //获取i18n的中英文类型,可以从session中进行获取到
	var i18nType="${sessionScope.i18nType}";
</script>

// html 可以使用标签进行获取中英文的内容,如下
<div class="searchText"><i18n:i18n value="button.search" /></div>

//在src 下创建资源文件
i18n_en_US.properties
i18n_zh_CN.properties

//数据 button.search 为在资源文件中进行配置
button.search=Search
button.search=搜索

或者

也可以直接使用 ${i18n.button} ,但这使用这种方式的话,在properties的资源文件中的KEY必须以字母开头,并且不能包含
. - 等特殊字符,需要使用下划线进行连接,个人觉得还是使用上面的方式好一点,虽然需要多写一点代码,但没有这么多限制

当然了,你也可以使用

<div class="itemNum_${session.i18nType}"></div>

这种方式,使中英文显示不同的css样式,如 itemNum_en_US/itemNum_zh_CN

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值