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

如何解决Java WEB应用中的乱码问题

 
阅读更多

抄自:http://blog.csdn.net/darxin/article/details/5036100

当我们通过Java程序员的视角来浏览网页时会发现:一方面用户端浏览器(IE或Firefox)以表单或链接的方式提交HTTP请求同时又处理HTTP服务器发出的响应数据,将其中的数据流(HTML数据或其它种类的数据)以适当的方式展示给使用者浏览。另一方面在Java WEB应用服务器上,一个HTTP请求可以由一个Servlet类或一个JSP网页来处理,请求数据来自于HttpServletRequest,响应数据发送至HttpServletResponse。通过用户端提交请求、服务器端处理请求、服务器端返回响应数据以及用户端处理响应数据四个步骤组成了一次HTTP请求的全部过程。数据在这四个重要环节中进行传输时,都将以指定的编码方式进行编码或解码。如果处理不当就会出现乱码问题。

用户端的处理

当用户端发出一个HTTP请求时,一个如下格式的数据将发送给服务器端:

<request-line>
<headers>
<CRLF>
[<request-body><CRLF>]

关于HTTP请求的格式,可以在HTTP协议与HTML表单(再谈GET与POST的区别)中了解更多的内容。
在此,request-line与request-body均需要进行相应的编码处理。

request-line的编码处理

request-line中的URL部分必须以application/x-www-form-urlencoded方式编码。编码时使用的字符集是当前网页在浏览器上显示时所使用的字符集。

JDK中专门有两个类处理application/x-www-form-urlencoded类型的数据,它们是URLEncoder及URLDecoder。当网页上的数据需要手动进行URLEncoding处理时,可使用URLEncoder类完成编码工作。需要手动进行URLEncoding处理的位置包括:

  • 链接(<a></a>)中的href标签属性;
  • 以POST方式提交的表单(<form></form>)中的action标签属性。

例如,网页上不应该产生这样的链接:

 

  1. <!-- 不正确的写法 -->  
  2. <a href="/hello/checkUser.html?opt=中文>使用者身份验证"</a>  

 

正确的写法是:

 

  1. <!-- 使用UTF-8字符集进行URLEncoding的结果 -->  
  2. <a href="/hello/checkUser.html?opt=%E4%B8%AD%E6%96%87">使用者身份验证</a>  

 

为此,方案之一可以在JSP网页上使用脚本化语言进行URLEncoding处理。如:

 

  1. <%@page import="java.net.URLEncoder"%>  
  2. <a href="/hello/checkUser.html?opt=<%=URLEncoder.encode("中文", "UTF-8")%>">使用者身份验证</a>  

 

request-body的编码处理

request-body只有在POST提交的方式下才会产生。request-body的编码方式由表单的enctype标签属性指定,同request-line一样,编码request-body时使用的字符集也是当前网页在浏览器上显示时所使用的字符集。request-body的编码过程由客户端浏览器自动完成,不需要额外的编程处理。

服务器的处理

相对于用户端,服务器端在接收到HTTP请求时提供了两种处理请求数据的方式:自动处理与不处理。
服务器一般会自动处理application/x-www-form-urlencoded类型的数据(包括request-line及request-body中的数据),就servlet(Servlet类或JSP网页)而言,可以通过request对象的getParameter()或getParameterValues()取得这些数据。对于除此以外的其它MIME类型的数据,HTTP服务器则是将处理的过程直接交到了与HTTP请求相对应的servlet(Servlet类或JSP网页)身上。
例如用户端有以下表单被提交:

 

  1. <form action="checkUser.html?opt=xxx" method="POST">    
  2.     <input type="text" name="username" value="yyy"/>    
  3.     <input type="text" name="username" value="zzz"/>    
  4.     <inupt type="submit" value="submit"/>    
  5. </form>  

  

 

表单提交时经服务器端自动处理后与checkUser.html相对应的servlet(Servlet类或JSP网页)可以通过下面的方式取得数据:

 

  1. String opt = request.getParameter("opt");  
  2. String[] users = request.getParameterValues("username");  

 

默认情况下,服务器对于接收到的application/x-www-form-urlencoded类型数据进行字符集为ISO-8859-1的URLDecoding处理,经过处理之后的字符串内码为ISO-8859-1。对于没有附加任何设置的HTTP服务器而言,我们的servlet在取得数据之后必须进行相应的解码处理,生成内码为UTF-16(unicode)的字符串。
例如对于用户端请求数据中以UTF-8字符集进行URLEncoding的数据,servlet需要进行如下方式的解码:

 

  1. String opt = request.getParameter("opt");  
  2. if (opt!=null && !"".equals(opt)) {  
  3.     opt = new String(opt.getBytes("ISO-8859-1"), "UTF-8");  
  4. }  

 

为了避免这种额外的编码/解码处理,也就是说让服务器了解到用户端在URLEncoding时所使用的字符集,从而直接进行相应字符集的URLDecoding处理,不同的HTTP服务器提供了不同的解决方案。
以Tomcat为例,Tomcat自动解码request-line的处理方式由Tomcat的配置文件server.xml指定。在server.xml中的Connector标签中提供了URIEncoding标签属性,只要为其指定解码用的字符集,Tomcat就会自动解码request-line中经过application/x-www-form-urlencoded编码处理的数据。例如:

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

Tomcat自动解码request-body的处理方式是设置request的characterEncoding值。如:

request.setCharacterEncoding("UTF-8");

但是这一操作必须提前在filter中完成,在servlet中使用此方法已经不起作用了。filter的例子如下:

 

  1. import java.io.IOException;  
  2. import javax.servlet.Filter;  
  3. import javax.servlet.FilterChain;  
  4. import javax.servlet.FilterConfig;  
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.ServletRequest;  
  7. import javax.servlet.ServletResponse;  
  8.   
  9. public class CharacterEncodingFilter implements Filter {  
  10.   
  11.     private String encoding;  
  12.   
  13.     public CharacterEncodingFilter() {  
  14.         encoding = null;  
  15.     }  
  16.   
  17.     public void destroy() {  
  18.         encoding = null;  
  19.     }  
  20.   
  21.     public void doFilter(ServletRequest request, ServletResponse response,  
  22.             FilterChain chain) throws IOException, ServletException {  
  23.   
  24.         request.setCharacterEncoding(encoding);  
  25.         chain.doFilter(request, response);  
  26.     }  
  27.   
  28.     public void init(FilterConfig filterConfig) throws ServletException {  
  29.   
  30.         encoding = filterConfig.getInitParameter("encoding");  
  31.         if (encoding == null || "".equals(encoding)) {  
  32.   
  33.             encoding = "UTF-8";  
  34.         }  
  35.     }  
  36. }  

 

我们可以在web.xml使用这个filter。web.xml的相应配置如下:

 

  1. <filter>  
  2.     <filter-name>Character Encoding Filter</filter-name>  
  3.     <filter-class>  
  4.         CharacterEncodingFilter  
  5.     </filter-class>  
  6.     <init-param>  
  7.         <param-name>encoding</param-name>  
  8.         <param-value>UTF-8</param-value>  
  9.     </init-param>  
  10. </filter>  
  11. <filter-mapping>  
  12.     <filter-name>Character Encoding Filter</filter-name>  
  13.     <url-pattern>/*</url-pattern>  
  14. </filter-mapping>  

 

通过上述两种方式的预处理,在servlet中取出的数据可以不必进行ISO-8859-1解码而直接使用。

字符集的选择

在处理application/x-www-form-urlencoded类型的数据过程中,需要注意的另一个问题是字符集的选择问题。如上所述,不论是request-line还是request-body,其URLEncoding所使用的字符集都是当前网页在浏览器上显示时所使用的字符集。而这个信息又是HTTP服务器端生成HTML网页时,在HTTP响应中提供的。
当HTTP服务器接收到一个HTTP请求时,服务器总是需要向用户端发送一个HTTP响应。HTTP响应数据与HTTP请求数据格式相同,同样由以下几个部分组成:

<response-line>
<headers>
<CRLF>
[<response-body><CRLF>]

下面描述的是请求一个HTML网页数据时服务器的响应信息:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Content-Length: 265
Date: Thu, 17 Dec 2009 05:20:36 GMT

 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>test</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
[End]

其中headers的Content-Type指定了数据流的数据格式以及显示用的字符集。这一指标可以通过以下几种方式指定:
1. HTML网页
在HTML网页的<head></head>中存在多个<meta/>标签,其中可以设置Content-Type。例如:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

2. JSP网页
JSP网页中,除了<meta/>标签之外,还需要在JSP网页头部设置如下代码:

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

3. Servlet类
如果要在Servlet类中通过response向用户端传送HTML数据,需要在传送前指定Content-Type。代码如下:

response.setContentType("text/html;charset=UTF-8");

通过上述三种方式,可以确保响应数据传送到用户端浏览器时,浏览器使用正确解码方式和字符集显示其内容。

结束语

总之,Content-Type是联系用户端与服务器端的纽带,通过这一指标,双方得以对相关的数据进行正确的编码与解码。只要了解了Content-Type的作用以及使用方法,乱码问题就会迎刃而解。

分享到:
评论

相关推荐

    Java Web开发中文乱码问题的研究与解决.pdf

    在利用Servlet/JSP技术开发java Web应用程序的时候,不可避免的会遇到中文乱码问题,本文首先介绍了Web应用中常用的编码方式,然后分析了J2EE平台下Web应用中文乱码问题产生的原因,并在此基础上针对不同情况提出了解决...

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

    对Java Web应用开发中的中文乱码问题的研究与解决

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

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

    毕业设计-Java Web应用中的中文乱码的研究

    该毕业设计课题是Java Web应用中的中文乱码问题的研究和解决。 本人当年呕心沥血,综合网络之精华,得此大作,\(^o^)/~。 本设计在对java在编码上的各种知识有比较深刻的讲述。

    Java Web开发中的乱码问题分析及解决方案研究 (1).pdf

    在利用JSP/Servlet技术开发java Web应用程序的时候,经常会遇到中文乱码问题,本文首先介绍了Web应用中常见的编码方式,然后分析了J2EE平台下Web应用中文乱码产生的原因,并针对不同情况给出了解决方法。

    Java Web中文乱码处理研究.pdf

    在java Web应用开发常见的问题中,中文的乱码问题在页面中没有统一的方法解决,造成程序员浪费大量的时间与精力且代码效率不高,因此提出了新的乱码算法,并设计了通用的乱码处理器,提高了程序员的工作效率.

    《Java Web开发与实战--Eclipse+Tomcat+Servlet+JSP整合应用》.(刘伟,张利国).[PDF].zip

    上传、java mail和分页显示、web编程中文乱码问题及解决方案、应用程序的打包和部署等。书中还深入讲解了客户端验证框架jsvalidation、在线文本编辑器fckeditor和apache commons的一些类库等功能强大的实用开发工具...

    Java Web应用开发:servlet.ppt

    如何向客户端发送响应 知道如何解决web开发中的中文乱码问题,知道乱码问题产生的原因和解决方法 会debug服务端代码 什么是Servlet Servlet是Java web应用中最核心的组件,完全用Java语言编写,它运行于服务端,它...

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

    全书一共被压缩为5个rar,这是第二个!...21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化与本地化 621 21.5.1 locale 621.. 21.5.2 资源包 623 ...

    Java Web开发与实战:Eclipse+Tomcat+Servlet+JSP整合应用(含光盘源代码)

    主要内容包括web应用程序运行原理、主流集成开发工具(eclipse/myeclipse)和运行环境(tomcat)的配置和使用、servlet、jsp、jdbc、jsp表达式语言(el)、servlet监听器和过滤器、定制标记库、jstl、mvc模式、dao...

    html 中文乱码 HTML超链接中文乱码问题分析及解决方法

    Vm中一个超链接URL需要拼接中文作为Get请求的参数。...这个默认字符集在Eclipse里跑main()方法和在Tomcat里跑Web应用,得到的结果不一样,所以影响了编码的结果。 复制代码代码如下: /** * Translates

    Java Web之高级应用,以ppt的形式呈现

    Java Web之高级应用,内容包括Tomcat中的类...为Tomcat配置Https协议功能,为站点增加自动登和单点登录功能,解决Web开发中的相对路径问题,为网站配置相同页眉和页脚的技巧,总结分析Web开发中的各种字符乱码问题。

    Servlet 中文乱码解决工具类

    由于Web容器使用了ISO-8859-1的编码格式,所以在Web应用的业务处理中也会使用ISO-8859-1编码格式。虽然浏览器提交的请求使用的是中文编码格式UTF-8,但经过业务处理中的ISO-8859-1编码,仍然会出现中文乱码现象。...

    Web应用中的中文问题以及数据表乱码.

    在Web java 开发中 经常 会碰到 中文乱码的情况, 或者数据库中的不支持中文等情况,此文档可以帮助你。

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

    全书一共被压缩为5个rar,这是第三个!...21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化与本地化 621 21.5.1 locale 621.. 21.5.2 资源包 623 ...

    java语音及web乱码

    为应用程序加上语音能力有什么好处呢?粗略地讲,是为了趣味

    JavaWeb应用中文乱码的解决方案 (1).pdf

    分析了java Web应用中产生中文乱码的原因,归纳总结了产生中文乱码的几种情况,根据每种情况给出了多种解决方案,并分析了每种解决方案各自的优缺点以及适用场合,为java Web程序员提供了参考和借鉴。

    深入体验Java Web开发内幕

     本书适合所有Web应用的开发人员、Java程序员在工作和学习中参考阅读,也适合作为相关专业本科生、研究生的学习参考资料,也可作为相关培训机构的培训教材。 【作者简介】  张孝祥中国著名IT培训教育...

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

    全书一共被压缩为5个rar,这是第四个!...21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化与本地化 621 21.5.1 locale 621.. 21.5.2 资源包 623 ...

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

    1.4.1 Web应用服务工作原理 1.4.2 web应用服务器汇总 1.4.3 获取Tomcat 1.4.4 熟悉Tomcat的五脏六腑 1.5 JavaWeb开发利器之Eclipse 1.5.1 获取Eciipse 1.5.2 运行Eclipse 1.5.3 打造中文版Eclipse 1.6 做好项日开发...

Global site tag (gtag.js) - Google Analytics