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

原创 2009年12月19日 07:18:00

Creative Commons License
本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。

 

 

当我们通过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标签属性。

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

正确的写法是:

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

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网页)身上。
例如用户端有以下表单被提交:

  

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

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

为了避免这种额外的编码/解码处理,也就是说让服务器了解到用户端在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的例子如下:

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

通过上述两种方式的预处理,在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的作用以及使用方法,乱码问题就会迎刃而解。

web应用开发中中文乱码问题

web应用中中文乱码问题在java程序中,出现中文乱码问题的原因的根源在于java程序和其他存储媒介互换数据时,两者编码方案不同。 常见的中文字符编码: GB2312-80 GB2312是简体汉字...
  • destination_zhy
  • destination_zhy
  • 2016年05月18日 13:04
  • 2440

web开发中文乱码问题及解决方案

在web应用开发过程中,经常会碰到中文乱码的问题,下面是常见的导致中文乱码的问题以及解决方案(tomcat) 1.JSP页面中包含中文不能保存,eclipse中提示需保存为UTF-8 解决的办法是在j...
  • sunmun
  • sunmun
  • 2016年07月14日 13:09
  • 1357

使用WebStorm开发web前端 网页中文乱码问题的解决方案

试了很多种解决网页显示中文乱码问题的方式,最后发现统一更改编码格式的方法才是正确有效而且一劳永逸的。 具体方法:file ----->  settings 搜索encoding 在fileenco...
  • u012954255
  • u012954255
  • 2015年04月16日 10:35
  • 16950

Java Web中常见乱码问题的分析与解决

Java Web中常见乱码问题的分析与解决 get请求参数乱码 post请求参数乱码 同时处理Get和Post两种提交方式的编码问题 服务器发送给浏览器的乱码问题 在jsp页面中,中文显示乱码...
  • u013905744
  • u013905744
  • 2016年09月07日 09:24
  • 2013

javaweb 解决请求相应的乱码问题

在学习javaweb过程中由于软件设计者都是外国人,他们所支持的编码都是ISO8859-1对于我们中国人来讲必须是中文,所以我们一般使用的编码就是utf-8或者GBK,然而开发工具都是用ISO8859...
  • chenfengdejuanlian
  • chenfengdejuanlian
  • 2015年12月28日 13:21
  • 1278

JavaWeb的各种中文乱码终极解决方法

一、Servlet输出乱码 1. 用servlet.getOutStream字节流输出中文,假设要输出的是String str ="钓鱼岛是中国的,无耻才是日本的"。 1.1 若是本地服务器与本地...
  • ld513508088
  • ld513508088
  • 2012年10月03日 16:05
  • 52399

java web项目各种乱码的解决方案

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本人声明。否则将追究法律责任。 作者:永恒の_☆ 地址:http://blog.csdn.net/chenghui0317...
  • ch656409110
  • ch656409110
  • 2013年08月25日 17:03
  • 21231

javaweb中中文乱码解决方法总结之response和request解决方法

javaweb中文乱码解决
  • bbb695480667
  • bbb695480667
  • 2016年12月21日 20:27
  • 4382

解决javaweb乱码问题

设置四个位置,可以解决百分之八九十的乱码问题。 1>.在eclipse或myeclipse中找到window-->preferences-->general-->workplace,将工程的编码格式...
  • qq441568267
  • qq441568267
  • 2016年07月27日 22:38
  • 139

Java Web乱码分析及解决方案(三)——响应乱码

响应乱码     请求乱码是客户端向服务器发送数据时,服务器解码错误。响应乱码则是服务器处理完请求后,输出到浏览器的数据被浏览器错误解码造成的显示乱码,这类乱码是最常见也是最直接的。造成这类乱码的情况...
  • HackerSaillen
  • HackerSaillen
  • 2015年07月22日 10:33
  • 2598
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何解决Java WEB应用中的乱码问题
举报原因:
原因补充:

(最多只允许输入30个字)