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了嘛? 为什么这里还要设一个编码转换?这个我就是不告诉你
JS与后台异步交换时乱码:
博主很强大啊,我在CSDN上面看到的贴子,被忽了个攸啊。。。。CSDN和ITEYE现在好多都不靠谱,我做一个AJAX请求传递,测了几天了。。。。。。。。。。真心感谢博主……
博主内容太少,这是真话。。没什么可以留恋的,和自述一样,一个懒家伙。哎