`
cynhafa
  • 浏览: 154905 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java开发,表单提交中发生中文乱码的问题

 
阅读更多

http://hi.baidu.com/studyaspnet/item/ecd636f4c87d9009d89e729c

Java开发,表单提交中发生中文乱码的问题。

Web开发的中文问题一直困惑大家,尤其是对于初上手者。这次有机会彻底解决研究了一下中文乱码的原因和解决方案,做个总结。

为什么会有中文乱码?

因为在默认情况下,HTTP的包都是以“8859_1”来编码的(没办法,谁叫这些标准都是老美定的)。“8859_1”是西文编码方式,对于英文字母没有任何问题,但是对于中文就不行了。所以,如果不做任何设定,直接将中文用“8859_1”来编码传递,那结果必然是乱码。

解决思路是什么?

好在老美还是有国际化眼光的,HTTP包的编码方式可以由用户指定。因此,只要事先指定好用相对应的编码方式来对传递内容(比如表单提交的中文等)进行编码,就可以顺利解决乱码的问题。

两个基本概念

在进入具体的解决方法之前,首先要对两个基本概念作一下解释。对于由表单提交的内容,HTTP有两种传递方式,分别是“GET”方式和“POST”方式。

“GET”方式就是将各参数直接通过HTTP的包头(head)来传递,简而言之就是直接通过我们所熟悉的网址(URL)来传递,所以我们经常能看到的在一个网址后面跟着许多复杂的由“?”和“&”构成的字符串,其实这就是需要传递的参数了。

“POST”方式则是将所需传递的参数包在HTTP的正文(body)中来传递。因此通过“POST”方式来进行传递,在浏览器的网址上面什么都看不见。

因此,相比较而言,“POST”隐蔽性较好;而“GET”方式使用起来比较容易,直接写URL就可以了。

综上所述,不难发现,解决中文乱码问题实际上就变为对这两种HTTP传递的编码方式进行适当的设定。当然,从解决问题的难易以及对系统架构的完美性角度着手,又分为以下三个层次:

1)入门方法,在所有的servlet和jsp中堆设定用的代码。

2)中级方法,对web伺服器进行配置。

3)高级方法,编写filter过滤器,对“POST”和“GET”独立过滤处理。

下面就具体描述各解决方法:

1)入门方法,在所有的servlet和jsp中“堆”写设定用的代码。

所谓入门方法,那就是现实十分简单,当然效果也是很好的。只是必须在每个相应的文件中写相同的设定代码,代码的重复性就比较大。

由前面所述,由于“POST”和“GET”方式的不同,因此对应着两种的设定方式也不同。

“POST”的情况下,如果服务器端脚本是一个servlet,那只要在doPost()方法里面插入一句

request.setCharacterEncode("GB2312");

需要注意的是,这句设定必须在所有从request对象做提取操作之前执行,如果类似于request.getParameter()的操作在前,那么系统将使用默认的“8859_1”编码方式,而忽略后面的设定代码。

如果服务器端是一个jsp脚本,那只要在该脚本的jsp申明部分做好设定即可:

<%@ page language="java" contentType="text/html; charset=gb2312" pageEncoding="gb2312"%>

如果是“GET”方式,也就是想通过URL来传递中文的话,稍微要麻烦些,首先因为浏览器地址栏是不支持中文的,也就是如果直接将中文放置在超级连接里面是无效的。因此需要在发送端对中文内容进行编码,比如:

URLEncoder.encoder("http://localhost/submit?name=张三","UTF-8");

“UTF-8”表示用这种编码方式对原字符串进行编码,编码好之后看到的结果是

http://localhost/submit?name=%D5%C5%C8%FD

所以我们经常看到在浏览器里面有众多的类似与“%D5%C5%C8%FD”这样的字符串,就是表明被UTF-8编码过了。由于UTF-8是跨各种平台的通用编码方式,因此比较常用于各种语言文字的传输载体。

相对应的,在接受方需要进行反向的解码即可,代码如下:

new String( request.getParameter("name").getBytes("8859_1"), "gb2312" );

这里可能会有一些疑问,为什么用“8859_1”来解码。事实上,我在第一次尝试的时候也曾使用“UTF-8”来尝试解码,结果出现乱码失败。究其原因,尽管“张三”被编码成了“%D5%C5%C8%FD”来传输,但是在传输过程中,“%D5%C5%C8%FD”仍旧需要由“8859_1”来编码打包成HTTP,因此,在接收端,自然先需要由“8859_1”来还原到“%D5%C5%C8%FD”的“UTF-8”格式,然后再由“UTF-8”还原到“GB2312”。

所以这样也不难理解为什么所谓“浏览器地址栏是不支持中文”,不能直接用中文而要用“UTF-8”来通过“8859_1”来打包了,原因就是“%D5%C5%C8%FD”这串类似于密码般的字符串本身就是西文字符,用“8859_1”编解码没有任何问题。而中文由于是2byte一个汉字,直接用西文方式来编解码自然就会出现问题。这也就是为什么称“UTF-8”为“跨各种平台的通用编码方式”了。

背景小资料:

由于“UTF-8”是通用编码方式,因此所有的语言格式均可以转换为“UTF-8”,在日益国际的今天,多语言的系统要求越来越多,因此强烈建议使用“UTF-8”来做为系统统一的编解码方式,从而彻底解决中文乱码的问题。

“UTF-8”为了能做到兼容所有语言的编解码,因此每一个字符均用2个byte来编码。这样就造成了存西文字符时需要多一倍的空间。这也算是为了通用而付出的代价了。

2)中级方法,对web伺服器进行配置

可想而知,相对于“堆”写大量代码,配置一下web伺服器config文件来解决中文乱码问题就显得优雅许多。但是由于各种web伺服器的情况不同,其配置方法也不尽相同。因此,其兼容性是个比较大的问题。

这里列举一下,如何通过修改Tomcat的conf配置文件来解决中文乱码的问题。

找到Tomcat的配置文件server.xml中的Connector这一行,为其添加一个如下的属性

URIEncoding = "GB2312"

这样就指定了使用“GB2312”来进行编解码。不过需要注意的是,tomcat4.x以以前的版本由于蒋“POST”和“GET”等同视之,因此这样一句设定就可以适用于两种方法。而到了tomcat5.x以后,两种方式就分开处理了。因此在tomcat5.x的情况下,只做这个设定,那仅仅对“POST”方式有效,“GET”方式仍然会得到乱码。

不过好在tomcat5.x考虑到了这个问题,提供了一个附加的参数:

useBodyEncodingForURI = "true"

如果做了这样的设定,那5.x就将兼容4.x而“POST”和“GET”等同视之。

3)高级方法,编写filter过滤器,对“POST”和“GET”独立过滤处理。

高级方法,顾名思义,就是可以脱离于任何平台,同时又免去冗余的队旗代码工作的解决方案——编写过滤器,Filter。

首先编写一个过滤器SetCharacterEncodingFilter

public class SetCharacterEncodingFilter implements Filter {

protected String encoding = null;

protected FilterConfig filterConfig = null;

protected boolean ignore = true;

// --------------------------------------------------------- Public Methods

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){

HttpServletRequest httpServletRequest = (HttpServletRequest) request;

if(httpServletRequest.getMethod().toLowerCase().equals("post")){

//如果是POST方法

request.setCharacterEncoding(encoding);

}

else{

//如果是GET方法

//非常抱歉,我还有没有找到很好的对应get方法的代码

//一旦完成了这部分代码,马上添加在这里。

//!·#¥%……—*()——+|

}

}

}

// 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 Methods

protected String selectEncoding(ServletRequest request) {

return (this.encoding);

}

}

编写完过滤器以后,需要对其进行部署,也就是在web.xml中做个配置:

在<display-name>标签之后,添加:

<filter>

<filter-name>Set Character Encoding</filter-name>

<filter-class>com.zavax.utility.filters.SetCharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF8</param-value>

</init-param>

<init-param>

<param-name>ignore</param-name>

<param-value>true</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>Set Character Encoding</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>


分享到:
评论

相关推荐

    Java Web应用开发中的中文乱码问题研究.pdf

    在java Web应用开发中,软件开发人员最容易遇到的问题就是中文的乱码问题,其中最常见的有两种,JSP页面中文显示乱码和表单提交参数中文乱码。本文通过深入分析这两种中文乱码问题产生的原因,分别给出了对应的解决方案...

    java+jsp+mysql开发 web项目处理中文乱码问题

    Jsp输出中文的乱码问题,获取表单提交的数据时的中文乱码问题,url中的中文问题,数据库中采取的编码方式不同于utf-8怎么办

    tomcat过滤器,处理表单提交出现乱码

    处理表单提交页面出现乱码现象,第三方开发。

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    3.10.1 表单提交中文数据乱码 3.10.2 如何在超链接中传递多个参数 3.10.3 重定向后出现404错误 3.11 精彩回顾 第4章 体验面向对象 1IavaBean技术 4.1 本章学习任务 4.1.1 本章知识体系 4.1.2 实例开发任务 4.2 ...

    从J2SE到J2EE知识点介绍

    2. 表单提交中文时出现乱码 134 3. 关于jsp在MyEclipse中打开的乱码问题 138 4. 关于html页面在eclipse中打开出现乱码情况 139 5. JSP页面通过URL传递中文参数的乱码问题 139 四、 Struts2 140 (一) 基于struts2的...

    《程序天下:J2EE整合详解与典型案例》光盘源码

    第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 ...15.11 解决Spring的中文乱码问题 15.12 运行验证程序 15.13 小结

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (2)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE ...15.11 解决Spring的中文乱码问题 15.12 运行验证程序 15.13 小结

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (1)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE ...15.11 解决Spring的中文乱码问题 15.12 运行验证程序 15.13 小结

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (3)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE ...15.11 解决Spring的中文乱码问题 15.12 运行验证程序 15.13 小结

    J2EE实验指导书*******

    1、创建web过滤器实现form表单post提交的中文乱码 32 2、配置中文乱码过滤器 32 3、创建登录验证的过滤器并配置 32 四、实验报告 32 实验十四 JSP+Servlet+JavaBean开发模式 33 一、实验目的 33 二、实验环境 33 三...

    Java学习笔记-个人整理的

    {2.8}框架中移动的小球}{59}{section.2.8} {2.9}抽象与接口}{59}{section.2.9} {2.10}访问控制}{60}{section.2.10} {2.10.1}类的属性}{60}{subsection.2.10.1} {2.10.2}类的方法}{61}{subsection.2.10.2} {...

    asp.net知识库

    帮助解决网页和JS文件中的中文编码问题的小工具 慎用const关键字 装箱,拆箱以及反射 动态调用对象的属性和方法——性能和灵活性兼备的方法 消除由try/catch语句带来的warning 微软的应试题完整版(附答案) 一个...

    ssh(structs,spring,hibernate)框架中的上传下载

    FormFile的属性来获取表单提交的文件数据。  工程的类按SSH的层次结构划分为数据持久层、业务层和Web层;WEB-INF下的applicationContext.xml为Spring的配置文件,struts-config.xml为Struts的配置文件,file-...

    HttpClient以及获取页面内容应用

    1.6.2Post提交表单(模拟表单提交) /** * post方式提交表单(模拟用户登录请求) */ public void postForm() { // 创建默认的httpClient实例. CloseableHttpClient httpclient = HttpClients.createDefault...

Global site tag (gtag.js) - Google Analytics