javaWeb -- web中的乱码问题集

笔记摘要:

    本文总结了最近web学习中遇到的一些中文乱码问题,其实问题的关键就是,文件保存时的编码,以及服务端对提交的数据进行的编码,和浏览器的编码,只要这三个编码问题搞清楚,就能够彻底解决中文乱码问题,当然以后还会遇到其它类型的乱码问题,相信万变不离其宗。


一、HttpServletResponse向客户端输出中文数据的乱码问题


response向客户端输出数据有两种方式:getOutputStream和getWriter


方式一:使用getOutputStream()

实验:getOutputStream().write("中国".getBytes("utf-8"));出现乱码

原因: getBytes()默认为GB2312,这里指定utf-8,而浏览器是以默认的GB2312打开,所以会出现乱码问题


解决方法:

必须指定浏览器以什么码表解码

1. response.setHeader("content-type", "text/html;charset=utf-8");  //设置请求消息头为utf-8,让浏览器以utf-编码打开

2. <meta http-equiv="" content="">来模拟响应头信息


方式二:getWriter(),获得一个字符输出流

实验:response.getWriter().write("中国");出现乱码


原因:

     因为这里获取到的是字符流,所以服务器在返回给浏览器的时候会转换成字节数据,需要进行编码,这时查的是ISO8859-1码表,ISO8859-1码表

     中没有中文,所以查到的是"??",而服务器是以GB2312打开,GB2312是兼容ISO8859-1的,所以浏览器直接就输出"??"

 

   解决方案:

方式一

response.setHeader("Content-type", "text/html;charset=utf-8");//设置请求消息头为utf-8,让浏览器以utf-编码打开

response.setCharacterEncoding("utf-8");//设置服务器解析时的编码格式为utf-8


方案二

response.setContentType("text/html;charset=utf-8"); 等价于上面两句


建议:

   在使用response.setContentType("text/html;charset=utf-8");的时候加上 

 response.setCharacterEncoding("utf-8");这样更易于阅读


二、HttpServletRequest请求乱码

提交请求的方式

超链接,表单,直接在服务栏中请求


POST表单

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
	<html>
		<head>
			<title>3.html</title>
		</head>
		<body>
			<a href="/day05/servlet/ConfusingCodeDemo?user=zhangsan&psw=12345">使用超链接提交数据</a>
			<hr>

GET表单

			<form action="/day05/servlet/ConfusingCodeDemo">
				用户名<input type="text" name="user">
				密码<input type="password" name="psw">
				<input type="submit" value="提交">
			</form>
			POST
			<hr>
			<form action="/day05/servlet/ConfusingCodeDemo" method="POST">
				用户名<input type="text" name="user">
				密码<input type="password" name="psw">
				<input type="submit" value="提交">
			</form>
		</body>
	</html>
	

问题原因:

在提交数据的时候,如果是中文(一般默认为GBK),在提交给服务端,在request处理的时候会进行ISO8859-1编码,而ISO8859-1编码不支持GBK,所以会解析成一些乱码,返回给浏览器


POST方式提交解决方法

request.setCharacterEncoding("GB2312");//放在request.getParameter()前面才有效

但是这种方式只对POST提交有用


GET方式提交解决方法(通用,也可以用于POST方式)

先进行ISO8859-1编码,以便服务器端可以识别,然后再使用ISO8859-1编码的字节进行GB2312解码,显示中文

String user = request.getParameter("user");

user = new String(user.getBytes("ISO8859-1"),"GB2312");//先进行ISO8859-1编码,这样服务器端可以识别,然后再使用GBK编码,提交给浏览器


可同时解决POST和GET(不推荐)

修改tomcat的配置文件:http://localhost:8080/docs/config/http.html

URIEncoding 指定服务端的编码

useBodyEncodingForURI :设为true,则POST的提交方式:request.setCharacterEncoding("GB2312");对GET方式也有用


三、实现文件下载时的中文问题

利用response将HTTP的响应头"content-disposition"设置为"attachment;filename=xxx"即可实现文件下载功能

注意:

    如果文件名中包含中文,则文件名要进行URL编码:URLEncoding.encode('卡拉.jpg','utf-8');如果不进行编码则文件名显示错误并且不可下载。

private void  download(){
String urlName = URLEncoder.encode("考拉.jpg","utf-8");//当响应给浏览器的文件名为中文时,需要进行URL编码,否则出现乱码  
        response.setHeader("content-disposition","attachment;filename="+urlName);  
//      response.setHeader("content-disposition","attachment;filename=Koala.jpg");//响应给浏览器时文件名是英文时,可以直接下载  
        InputStream in = this.getServletContext().getResourceAsStream("/Koala.jpg");//获取本地文件并封装成流  
        OutputStream out = response.getOutputStream();  
          
        //文件复制  
        int len = 0;  
        byte[] buf = new byte[1024];  
        while((len=in.read(buf))!=-1){  
            out.write(buf,0,len);  
        }  
        in.close();  
}

四、JSP中的乱码问题

 使用page指令解决JSP中文乱码

1、JSP程序存在有与Servlet程序完全相同的中文乱码问题

a) 输出响应正文时出现的中文乱码问题 

b) 读取浏览器传递的参数信息时出现的中文乱码问题


2、JSP引擎将JSP页面翻译成Servlet源文件时也可能导致中文乱码问题  (文件编码与解析时的编码不同)

a) JSP引擎将JSP源文件翻译成的Servlet源文件默认采用UTF-8编码,而JSP开发人员可以采用各种字符集编码来编写JSP源文件,因此,JSP引擎将JSP源文件翻译

  成Servlet源文件时,需要进行字符编码转换。 

b) 如果JSP文件中没有说明它采用的字符集编码,JSP引擎将把它当作默认的ISO8859-1字符集编码处理。


3 如何解决JSP引擎翻译JSP页面时的中文乱码问题 

通过page指令的contentType属性说明JSP源文件的字符集编码

page指令的pageEncoding属性说明JSP源文件翻译成servlet时的字符集编码

其实只用设置pageEncoding即可,此属性一旦设置好,翻译引擎会间接帮我们设置content-type属性.


posted @ 2013-03-23 23:25  积小流,成江海  阅读(391)  评论(0编辑  收藏  举报