那些年JavaWeb的各种中文乱码终极解决方法!!
原帖: http://blog.csdn.net/chenshufei2/article/details/8010149
一、Servlet输出乱码
1. 用servlet.getOutStream字节流输出中文,假设要输出的是String str ="钓鱼岛是中国的,无耻才是日本的"。
1.1 若是本地服务器与本地客户端这种就不用说了,直接可以out.write(str.getBytes())可以输出没有问题。因为服务器中用str.getBytes()是采用默认本地的编码,比如GBK。而浏览器也解析时也用本地默认编码,两者是统一的,所以没有问题。
1.1 若服务器输出时用了, out.write(str.getBytes("utf-8"))。而本地默认编码是GBK时(比例在中国),那么用浏览器打开时就会乱码。因为服务器发送过来的是utf-8的1010数据,而客户端浏览器用了gbk来解码,两者编码不统一,肯定是乱码。当然,你也可以自己将客户端浏览器的编码手工调用下(IE菜单是:查询View->编码encoding->utf-8),但是这种操作很烂,最好由服务器输出响应头告诉,浏览器用哪种编码来解码。所以要在服务器的servlet中,增加response.setHeader("content-type","text/html;charset=utf-8"),当然也可直接用简单的response.setContentType("text/hmtl;charset=utf-8")。两种的操作是一样一样的。
2. 用servlet.getWirter字符流输出中文,假设要输出的是String str ="钓鱼岛是中国的,无耻才是日本的"。
2.1 若写成out.print(str)输出时,客户端浏览器显示的将全是多个?????的字符,代表在编码表中肯定就找不到相应的字符来显示。原因是:servlet.getWriter()得到的字符输出流,默认对字符的输出是采用ISO-8859-1,而ISO-8859-1肯定是不支持中文的。所以肯定要首先要做的第一件事:是要将服务器对象输出字符能支持中文的。其次服务器向客户端写回的响应头要告诉客户端是用了哪种编码表进行编码的。而实现这两个需求,只需要response.setContentType("text/hmtl;charset=utf-8")。就搞定了。特别注意:response.setContentType("text/html;charset=utf-8")要放在PrintOut out = response.getWriter()代码的前面,否则只是有告诉客户端用什么码表编码的功能,而服务器端还是用ISO-8859-1编码了。再特别提示下:在同一Servlet中的doGet或doPost方法中,不能既用response.getOutputStream又用response.getWriter,因为这两种response的响应输出字节流与字符流是冲突的,只能用其一。
二、Servlet文件下载,中文乱码情况。
关键是下载时响应头 content-disposition中attachment;filename=文件名。这个文件名filename不能是含有中文字符串的,要用URLEncoding编码进行编码,才能进行进行http的传输。如下代码示例:
[java] view plaincopy
//获取文件的URL地址
String realPath = getServletContext().getRealPath("/钓鱼岛是中国的无耻才是日本的历史证据.jpg");
//获取文件名: 钓鱼岛是中国的无耻才是日本的历史证据.jpg
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//指示响应流的类型不是text/html而是二进制流数据以指示下载
response.setContentType("application/octet-stream");
//注意这里一般都用URLEncoder的encode方法进行对文件名进行编码
String enFileName = URLEncoder.encode(fileName, "utf-8");
//enFileName文件名若含有中文必须用URLEncoding进行编码
response.setHeader("content-disposition", "attachment;filename="+enFileName);
//文件读取与输出,模板代码了...
InputStream in = new FileInputStream(realPath);
OutputStream out = response.getOutputStream();
int len = -1;
byte[] buf = new byte[1024];
while((len=in.read(buf))!=-1){
out.write(buf, 0, len);
}
in.close();
三、Servlet的response增加addCookie,cookie中value的中文码问题解决方法。
关于cookie的原理,见http://blog.csdn.net/chenshufei2/article/details/8009992。 若想将cookie中存放中文的值,必须用Base64编码后,发给客户浏览器端进入存储。而下次客户端浏览访问是带回来的cookie中的值,是经过Base64编码的,所以需要用Base64解码即可。 Base64编码主要是解决将特殊字符进行重新编码,编码成a-b、A-B、0-9、+与/,字符52,10个数字与一个+,一个/ 共64个字符。它的原理是将原来3个字节的内容编码成4个字节。主要是取字节的6位后,在前面补00组成一个新的字节。所以这样原来的3个字节共24,被编码成4个字节32位了。
具体代码示例如下:
[java] view plaincopy
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
String getUserName = request.getParameter("username");
PrintWriter out = response.getWriter();
String username = null;
//获取客户端提交过来的cookie数组。
Cookie[] cookies = request.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
//遍历cookie数组,找到含有username的key的cookie。
if (Constant.USER_INFO.equals(cookies[i].getName())) {
username = cookies[i].getValue();
//得到cookie的值后必须,进行Base64解码,因为前次生成cookie时,value是经过Base64编码。
username = Base64Coder.decode(username); //进行Base64解码
}
}
out.print(username + ",恭喜您登录成功......"+getUserName); //username从Cookie中得出来,getUserName从请求参数中
System.out.println(username+"------------");
String remember = request.getParameter("remember");
//中文必须要进行 base64进行加码,才能作为cookie的值
getUserName = Base64Coder.encode(getUserName);
//将编码后的中文username的作为cookie的value
Cookie cookie = new Cookie(Constant.USER_INFO, getUserName);
cookie.setPath(getServletContext().getContextPath());
if(null != remember){ //若选择中了,则将Cookie写进去,若没有选择中,则将以前的Cookie都置成空
cookie.setMaxAge(Integer.MAX_VALUE); //设置Cookie是Integer最大数,好似有70多年的存效吧。呵呵
}else{
cookie.setMaxAge(0); //设置成cookie马上失效,maxAge是cookie的存活时间
}
response.addCookie(cookie);
四、获取请求参数乱码
GET方式的乱码:
如<a href=”/demo5/servlet/RD2?name=中国”>CN</a>,直接用request.getParameter得到的字符串strCN将会乱码,这也是因为GET方式是用http的url传过来的默认用iso-8859-1编码的,所以首先得到的strCn要再用iso-8859-1编码得到原文后,再进行用utf-8(看具体页面的charset是什么utf-8或gbk)进行解码即可。new String(strCn.getBytes(“ISO-8859-1”),“UTF-8”);
[java] view plaincopy
String strCn = request.getParameter("name");
String name = new String(strCn.getBytes(“ISO-8859-1”),“UTF-8”);
这种方式操作比较麻烦的是,有一个参数要用iso-8859-1编码一次再解码一次。
POST方式的乱码:只需要request.setCharacterEncoding("UTF-8"):即可。
[java] view plaincopy
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
分享到:
相关推荐
JavaWeb中字节乱码filter解决办法,其中包括tomcat各个版本进行字符设置.
以下是一些关于JavaWeb中文乱码问题及其解决方案的关键知识点: 1. **字符编码基础**:理解字符编码是解决问题的第一步。常见的字符集有GBK、GB2312(简体中文)、Big5(繁体中文)以及Unicode家族的UTF-8、UTF-16...
JavaWeb 乱码问题终极解决方案 下面是从给定的文件中生成的相关知识点: 一、确认乱码发生的位置 在解决 JavaWeb 乱码问题时,首先要确认乱码的地方。出现乱码可能是浏览器显示问题,也可能是 Java 编码问题,也...
以下是对JavaWeb应用中文乱码的详细解析及解决方案: 1. **原因分析**: - **HTTP请求头编码不明确**:HTTP协议允许客户端通过`Content-Type`头指定请求内容的字符编码,如果未设置或设置错误,服务器可能无法正确...
开发中前台页面向后台传参,汉字乱码,看了好多网上的方法都解决不了,所以写了一个工具类,判断是乱码就转换,不乱码就不乱换,汉字字母符号自动判断。最后完美解决汉字乱码问题。
Java Web 技术开发中文乱码问题解决方案 本文档是基于 Java Web 技术开发中文乱码问题的深入探讨,旨在解决 Java Web 开发中中文乱码问题的根本办法。文章首先详细分析中文乱码问题产生的原因,然后提出合理的解决...
### javaweb项目中乱码的处理 在Java Web项目的开发过程中,经常遇到的一个问题是字符乱码。这不仅影响用户体验,还可能导致数据错误。本文旨在详细介绍如何解决Java Web项目中的乱码问题,包括如何统一开发环境、...
以下是从标题“javaweb乱码解决方法”和描述“通杀所有java乱码”中提炼出的关键知识点: ### 1. 设置HTML文档的字符集 在HTML头部通过`<meta>`标签指定文档的字符集。例如,如果希望使用GBK编码,可以在页面开头...
关于处理Javaweb中中文乱码的问题[收集].pdf
总结来说,解决JavaWeb开发中的中文乱码问题,关键在于正确地设置字符编码。使用`HttpServletResponse`的`setCharacterEncoding`和`setContentType`方法可以确保数据在传输过程中的编码与接收端的解码保持一致,从而...
解决JavaWeb开发中Jsp存储读取MySQL数据中文乱码的问题.pdf
JavaWeb开发技术-解决中文输出乱码问题 JavaWeb开发技术是指使用Java语言开发Web应用程序的技术,涵盖了从基本的Servlet和JSP到高级的框架和架构模式的各种技术。其中,解决中文输出乱码问题是JavaWeb开发中一个...
### 解决Javaweb乱码问题完整方案 在Javaweb开发过程中,字符编码问题经常困扰着开发者,特别是中文等多字节字符的处理。本文将详细讲解如何全面解决Javaweb中的乱码问题,确保网页内容正确显示。 #### 一、配置...
本文将详细讲解如何利用过滤器来解决JavaWeb中的乱码问题。 首先,我们需要理解JavaWeb中的乱码产生的原因。当用户通过浏览器提交数据时,如果服务器接收到的数据编码与服务器内部处理编码不匹配,或者JSP页面的...
### JavaWeb乱码问题分析与解决 #### 一、引言 在JavaWeb开发中,乱码问题是开发者经常遇到的问题之一。它不仅会影响用户体验,还会对数据的正确性造成潜在威胁。本文将针对请求乱码及响应乱码两种情况进行深入剖析...
通过上述方法,可以有效地解决JavaWeb开发中的中文乱码问题。最重要的是在整个项目中保持一致的字符编码设置,确保从用户输入到数据库存储再到页面展示的每一个环节都能使用相同的编码。此外,使用自定义过滤器来...
超全面javaweb第4天-_05_xml的中文乱码问题解决