JAVA的编码问题由来已久,这些编码问题包含程序内部编码,传输期编码,页面编码以及数据库编码方式等。 其实只要你在CODE时下意识的注意到这些问题,它就不是什么问题了,可是往往被人忽视,下面我会总结一下经常发生的情景以及解决方案

场景一 [程序内部实现标准编码]:

客户的过分的需求,需要在WEB SERVICE层某一个逻辑分支向外部输出’>’这个符号,这是一个很诡异的需求,因为只是一个小符号,所以没有必要将其放在数据库里从而节省请求开支,但是在JAVA代码里面,直接放一个这个符号,明显不合适,

[JAVA]

System.out.println(“>”)

[/JAVA]

上面的代码如果是个DEMO的话,完全没有问题,但是因为项目原因,这个项目会被布署在全球各地,所以直接放这个符号是危险的,它并不具备标准编码规范,所以这个时候,我就采用了ASII编码进行转码:

进行转码:

[JAVA]

private String decodeUnicode( final String dataStr ) {
int start = 0;
int end = 0;
final StringBuffer buffer = new StringBuffer();
while( start > -1 ) {
end = dataStr.indexOf( “\\\\u”, start + 2 );
String charStr = “”;
if( end == -1 ) {
charStr = dataStr.substring( start + 2, dataStr.length() );
} else {
charStr = dataStr.substring( start + 2, end);
}
char letter = (char) Integer.parseInt( charStr, 16 );
buffer.append( new Character( letter ).toString() );
start = end;
}
return buffer.toString();
}

[/JAVA]

进行解码:

[JAVA]

String s = decodeUnicode(“\\u221a”);

System.out.println(s);

[/JAVA]

场景一OVER。

场景二:[最常见的编码问题]

当小明将HELLO WORLD高心的上线后,程序没有任何问题,正当他嘴角上扬时,他发现,当他输入中文时,返回的结果是乱码!!!

乱码啊!!!

这个时候,就开始排除错误了吧:

第一步,检查JSP页面是否支持中文编码,这个很简单,你只需求将JSP上面正文部分加入“世界,你好”,发布后看看结果,中文显示正常与否。

若此步乱码,那么JSP的编码有问题,建议将JSP编码改为UTF-8,强烈建议一切开发环境都是UTF-8,个人强烈建议最好不要使用GB打头的编码方式。

第二步,  检查数据库是否支持中文,这个更简单了,直接进入SQL UI界面或是在DOS屏上测试一下,就可以排除,一般默认安装都不支持中文编码。

所以,强烈建议一切开发环境改为utf-8…

第三步,如果上面两步都没有问题,那么问题就出现在下面了。。。。

如果你走到了这步,几乎可以确定你是传输期编码不一致导致乱码.

这里也会出现分支,先说第一种极为常见的

HTTP层数据传输编码不一致:

这种情况可能是你的TOMCAT或JBOSS等容器的编码有问题,也有可能是你的一些插件或框架不支持中文,或者。。。。

不管三七二十一了,这种情况,直接用一个filter搞定..

[JAVA]

public class CharacterEncodingFilter implements Filter {
protected String encoding = null;
protected FilterConfig filterConfig = null;
protected boolean ignore = true;

public void destroy() {

this.encoding = null;
this.filterConfig = null;

}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {

// Conditionally select and set the character encoding to be used
if (ignore || (request.getCharacterEncoding() == null)) {
String encoding = selectEncoding(request);
if (encoding != null)
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
}
// Pass control on to the next filter
chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter(“encoding”);
String value = filterConfig.getInitParameter(“ignore”);
if (value == null)
this.ignore = true;
else if (value.equalsIgnoreCase(“true”))
this.ignore = true;
else if (value.equalsIgnoreCase(“yes”))
this.ignore = true;
else
this.ignore = false;

}
protected String selectEncoding(ServletRequest request) {

return (this.encoding);

}
}

[/JAVA]

在Web.xml中加入这个Filter,并配上相应编码,还是那句话,强烈建议使用UTF-8

[xml]

<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.HXZJ_WEB.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>

[/xml]

配置拦截条件,这里是全匹配

[JAVA]

<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

[/JAVA]

配上这个FILTER过后,相信,你的项目几乎不会再被乱码所困扰了。

 

JS与后台异步交换时乱码:

这种情况,其实很少见,一般也不会直接通过JS来传递信息,通常是将整个信息块封装在FORM表单里,进行传输,这样不会出现问题,但是某种情况下就很危险:

url = “dreamforce.me?message=’世界,你好'”,我深信你会悲剧的,后台接收到的值应该不出意外是乱码.

这个原因很简单,这样的显示传递,HTTP将会将字符进行解析成%U%%%这种格式,那后台接收到的值也就是解析过后的字符,显然已经面目全非了

网上有很多关于这种解决方案,我这里给出一个我项目中使用且稳定的方案:

[JAVA]

propertyValue = java.net.URLDecoder.decode(propertyValue, “UTF-8”);

[/JAVA]

就这一句搞定,再看看网络上各种方案,简直想拍砖。

有人这里会问,之前不是有filter了嘛? 为什么这里还要设一个编码转换?这个我就是不告诉你

 

One Reply to “关于JAVA编码问题”

  1. JS与后台异步交换时乱码:
    博主很强大啊,我在CSDN上面看到的贴子,被忽了个攸啊。。。。CSDN和ITEYE现在好多都不靠谱,我做一个AJAX请求传递,测了几天了。。。。。。。。。。真心感谢博主……

    博主内容太少,这是真话。。没什么可以留恋的,和自述一样,一个懒家伙。哎

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: