参考: 关于JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换
今天下载一个中文文件结果是404,文件在路径下存在,将文件名改成英文就可以下载了,所以应该是中文编码的问题。
环境:apache-tomcat-7.0.72
在网上找了一下方法,这些方法是对应服务器端乱码的情况
方法1
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
方法2
String usernameString = new String(name.getBytes("ISO-8859-1"),"gb2312");
方法3
request.setCharacterEncoding("gbk");
一次Http请求
浏览器【get/post】-->浏览器编码-->tomcat解析UR-->获取参数-->返回页面-->浏览器显示
对于的编解码过程
浏览器编码-->tomcat解码-->生成结果-->tomcat编码---->浏览器解码
情况一:中文URL
URL:http://localhost:9080/DataDiscoveryWeb/resources/doc/新建文本文档.txt (这是一个直接访问文件的URL)
问题:访问不到
问题原因:浏览器对中文URL进行编码---->tomcat使用了不同于浏览器的编码方式解码
1.浏览器对URL编码
各个浏览器对URL的编码不同
解决方法:手动将此中文进行编码:encodeURI(url),encodeURI编码默认使用的是utf-8编码方式
http://localhost:9080/DataDiscoveryWeb/resources/doc/新建文本文档.txt -----> http%3A%2F%2Flocalhost%3A9080%2FDataDiscoveryWeb%2Fresources%2Fdoc%2F%E6%96%B0%E5%BB%BA%E6%96%87%E6%9C%AC%E6%96%87%E6%A1%A3.txt
2.tomcat服务器对URL解码
当tomcat接收到该链接时,将会进行URL解码,即去掉"%",同时按照ISO8859-1编码识别。
tomcat 默认的解码为ISO-8859-1,所以解析成 http://localhost:9080/DataDiscoveryWeb/resources/doc/æ°å»ºææ¬ææ¡£.txt
解决方法:
设置tomcat的Server.xml文件<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
设置URIEncoding="UTF-8"后,tomcat解码为UTF-8,结果是 http://localhost:9080/DataDiscoveryWeb/resources/doc/新建文本文档.txt
情况二:Get请求参数中有中文
URL:http://localhost:8080/myServlet?name=力量
问题:接受参数乱码
问题原因:问题原因与情况一是一样的,浏览器对中文URL进行编码-------->tomcat使用了不同于浏览器的编码方式解码(浏览器对请求参数的编码和URL直接写中文编码可能不同)
浏览器编码: 1.直接地址栏上写http://localhost:8080/myServlet?name=力量 使用的是浏览器默认的编码
2.在页面上写http://localhost:8080/myServlet?name=力量,使用页面的ContentType定义的Charset进行编码,(jsp页面上的contentType="text/html;charset=gb2312")
我的JSP页面代码
<%@ page contentType="text/html;charset=gb2312" language="java" %> <html> <body> <h2>力量</h2> <a href="/myServlet?name=力量">跳转</a> <a href="/resources/doc/新建文本文档.txt">下载文件</a> </body> </html>
点击跳转,地址栏上变成 http://localhost:8080/myServlet?name=%C1%A6%C1%BF(使用的是contentType中的charset的编码方式)
点击下载文件,地址栏变成 http://localhost:8080/resources/doc/新建文本文档.txt(最终使用浏览器的编码方式 http://localhost:8080/resources/doc/%E6%96%B0%E5%BB%BA%E6%96%87%E6%9C%AC%E6%96%87%E6%A1%A3.txt)
解决方法:
方法1:与情况一的解决方法一样,修改tomcat server.xml ,<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>,不过此时页面的contentType中的charset也一定要设置为utf-8
方法2:在获取参数的时候自定义转码规则
String name = req.getParameter("name");
System.out.println(name);
String usernameString = new String(name.getBytes("ISO-8859-1"),"gb2312");//此处与页面的contentType中的charset一致
System.out.println(usernameString);
情况三:Post请求中参数带中文
URL:http://localhost:8080/myServlet 请求参数 name:力量
问题: 服务器中获取参数String name = req.getParameter("name") 乱码
原因:问题原因与情况一是一样的,浏览器对中文URL进行编码---->tomcat使用了不同于浏览器的编码方式解码,浏览器编码的方式是根据 contentType中的charset。
解决方法:
方法1:与情况一的解决方法一样,修改tomcat Server.xml ,<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>,不过此时页面的contentType中的charset也一定要设置为utf-8。
方法2:与情况二中的解决方法2一样,接收参数时转码 String usernameString = new String(name.getBytes("ISO-8859-1"),"gb2312");
方法3:request.setCharacterEncoding("gbk"); 一定要在request.getParameter("name")获取参数之前设置编码。
注意:HttpServletRequest.setCharacterEncoding()方法 仅仅只适用于设置post提交的request body的编码而不是设置get方法提交的queryString的编码。问题本质是get方式传递的参数内容默认编码方式问ISO8859-1,而且使用request.setCharacterEncoding("utf-8")也无法解决问题。