您的位置:首页 > 编程语言 > Java开发

终结解决Java Web开发过程中的中文乱码问题

2017-07-11 22:05 399 查看
网上很多关于Java Web开发过程中的中文乱码问题,我们前端后端都设置为UTF-8的编码,最后还是会发生乱码问题。

1、不同浏览器造成的问题

IE和Chrome会对URL的参数作不同的处理,比如,我们在地址栏敲入一下地址http://localhost:8080/Hello/homepage?name=汉语,参数中包括了中文,浏览器会对中文参数进行转码。

IE的转码为:http://localhost:8080/Hello/homepage?name=%BA%BA%D3%EF

Chrome转码为:http://localhost:8080/Hello/homepage?name=%E6%B1%89%E8%AF%AD

明显IE对参数进行了GBK的转码,Chrome对参数进行了UTF-8的转码,这直接导致了乱码的出现,而且非常不好解决,有时候解决不了。

但是百度,Google,维基百科却解决了,比如以下地址:

https://zh.wikipedia.org/wiki/%E6%B1%89%E8%AF%AD

https://zh.wikipedia.org/wiki/%BA%BA%D3%EF

维基百科都可以定位到汉语这个词条,百度,Google也是一样的。

2、不同版本Tomcat造成的问题

在Tomcat不同版本对编码的默认处理于是不一样的,Tomcat7(包括Tomcat7)之前的版本默认是iso-8859-1,tomcat 7之后的版本用的是UTF-8编码,截图为证:

Tomcat7:



Tomcat8:



解决办法:

这两个问题是相辅相成的。我们在前端使用什么编码的,在Tomcat中使用相同的编码方式进行解码,我们就能得到正确的值。

说起来是废话,我们看下例子:

在Tomcat的server.xml文件中,我们修改

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>


这个时候,我们使用Chrome浏览器,后台就能得到正确的值,但是我们用IE浏览器就得到了乱码,再也变不回来了,估计是字节被破坏了,同样的我们将URIEncoding改为GBK,就能直接直接获取IE访问的URL中文参数了,但是Chrome的中文参数就是乱码了,而且再也变不回来了。

但是我们可以取一个折中的办法,比如,我们在Tomcat将编码改为ISO-8859-1,然后在后端判断,作相应的处理:

String name = request.getParameter("name");
if(!StringUtils.isEmpty(name)) {
if(!isMessyCode(new String(name.getBytes("ISO-8859-1"), "UTF-8"))) {
logger.info("传过来的参数为:"+ new String(name.getBytes("ISO-8859-1"), "UTF-8"));
}else {
logger.info("传过来的参数为:"+ new String(name.getBytes("ISO-8859-1"), "GBK"));
}
}


isMessyCode判断乱码的函数为:

/**
* 判断字符是否是中文
*
* @param c 字符
* @return 是否是中文
*/
public static boolean isChinese(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
return true;
}
return false;
}

/**
* 判断字符串是否是乱码
*
* @param strName 字符串
* @return 是否是乱码
*/
public static boolean isMessyCode(String strName) {
Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
Matcher m = p.matcher(strName);
String after = m.replaceAll("");
String temp = after.replaceAll("\\p{P}", "");
char[] ch = temp.trim().toCharArray();
float chLength = ch.length;
float count = 0;
for (int i = 0; i < ch.length; i++) {
char c = ch[i];
if (!Character.isLetterOrDigit(c)) {
if (!isChinese(c)) {
count = count + 1;
}
}
}
float result = count / chLength;
if (result > 0.4) {
return true;
} else {
return false;
}

}


判断乱码的函数是我在网上找的,这样就能同时识别GBK和UTF-8的参数了,以ISO-8859-1作为中间编码。

但是有种情况,Tomcat的环境是固定的,你改了配置,让其他的项目都不能玩了,这肯定不行。如果Tomcat编码环境是ISO-8859-1的,我们就按以上的方法处理,如果Tomcat编码环境是UTF-8的,对于IE这样的浏览器,我们就要避免用户直接在地址栏输入地址,实在不行,我们就设计成restful风格的URL,中文path Info是作为UTF-8处理的,不受操作系统的影响,IE浏览器设置始终以UTF-8发送,默认是选中的。直接能得到path参数值,我还没看到Tomcat编码环境是GBK的,要是实在是GBK的,我们就只能设计避免用户在地址栏中包含中文的URL了。

如果文中有什么错误或者大家有什么更好的办法,请给我留言,共同探讨!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: