一、问题:
编码问题是JAVA初学者在web开发过程中经常会遇到问题,网上也有大量相关的文章介绍,但其中很多文章并没有对URL中使用了中文等非ASCII的字 符造成服务器后台程序解析出现乱码的问题作出准确的解释和说明。本文将详细介绍由于在URL中使用了中文等非ASCII的字符造成乱码的问题。
1、在URL中中文字符通常出现在以下两个地方:
(1)、Query String中的参数值,比如http://search.china.alibaba.com/search/offer_search.htm?keywords=中国
(2)、servlet path,比如:http://search.china.alibaba.com/selloffer/中国.html
2、出现乱码问题的原因主要是以下几方面:
(1)、浏览器:我们的客户端(浏览器)本身并没有遵循URI编码的规范(http://www.w3.org/International/O-URL-code.html)。
(2)、Servlet服务器:Servlet服务器的没有正确配置。
(3)、开发人员并不了解Servlet的规范和API的含义。
二、基础知识:
1、一个http请求经过的几个环节:
浏览器(ie firefox)【get/post】------------>Servlet服务器------------------------------->浏览器显示
编码 解码成unicode,然后将显示的内容编码 解码
(1) 浏览器把URL(以及post提交的内容)经过编码后发送给服务器。
(2) 这里的Servlet服务器实际上指的是由Servlet服务器提供的servlet实现ServletRequestWrapper,不同应用服务器的 servlet实现不同,这些servlet的实现把这些内容解码转换为unicode,处理完毕后,然后再把结果(即网页)编码返回给浏览器。
(3) 浏览器按照指定的编码显示该网页。
当对字符串进行编码和解码的时候都涉及到字符集,通常使用的字符集为ISO8859-1、GBK、UTF-8、UNICODE。
2、URL的组成:
域名:端口/contextPath/servletPath/pathInfo?queryString
说明:
1、ContextPath是在Servlet服务器的配置文件中指定的。
对于weblogic:
contextPath是在应用的weblogic.xml中配置。
<context-root>/</context-root>
对于tomcat:
contextPath是在server.xml中配置。
<Context path="/" docBase="D:/server/blog.war" debug="5" reloadable="true" crossContext="true"/>
对于jboos:
contextPath是在应用的jboss-web.xml中配置。
<jboss-web>
<context-root>/</context-root>
</jboss-web>
2、ServletPath是在应用的web.xml中配置。
<servlet-mapping>
<servlet-name>Example</servlet-name>
<url-pattern>/example/*</url-pattern>
</servlet-mapping>
2、Servlet API
我们使用以下servlet API获得URL的值及参数。
request.getParameter("name"); // 获得queryString的参数值(来自于get和post),其值经过Servlet服务器URL Decode过的
request.getPathInfo(); // 注意:pathinfo返回的字符串是经过Servlet服务器URL Decode过的。
requestURI = request.getRequestURI(); // 内容为:contextPath/servletPath/pathinfo 浏览器提交过来的原始数据,未被Servlet服务器URL Decode过。
3、开发人员必须清楚的servlet规范:
(1) HttpServletRequest.setCharacterEncoding()方法 仅仅只适用于设置post提交的request body的编码而不是设置get方法提交的queryString的编码。该方法告诉应用服务器应该采用什么编码解析post传过来的内容。很多文章并没 有说明这一点。
(2) HttpServletRequest.getPathInfo()返回的结果是由Servlet服务器解码(decode)过的。
(3) HttpServletRequest.getRequestURI()返回的字符串没有被Servlet服务器decoded过。
(4) POST提交的数据是作为request body的一部分。
(5) 网页的Http头中ContentType("text/html; charset=GBK")的作用:
(a) 告诉浏览器网页中数据是什么编码;
(b) 表单提交时,通常浏览器会根据ContentType指定的charset对表单中的数据编码,然后发送给服务器的。
这里需要注意的是:这里所说的ContentType是指http头的ContentType,而不是在网页中meta中的ContentType。
三、下面我们分别从浏览器和应用服务器来举例说明:
URL:http://localhost:8080/example/中国?name=中国
汉字 编码 二进制表示
中国 UTF-8 0xe4 0xb8 0xad 0xe5 0x9b 0xbd[-28, -72, -83, -27, -101, -67]
中国 GBK 0xd6 0xd0 0xb9 0xfa[-42, -48, -71, -6]
中国 ISO8859-1 0x3f,0x3f[63, 63]信息失去
(一)、浏览器
1、GET方式提交,浏览器会对URL进行URL encode,然后发送给服务器。
(1) 对于中文IE,如果在高级选项中选中总以UTF-8发送(默认方式),则PathInfo是URL Encode是按照UTF-8编码,QueryString是按照GBK编码。
http://localhost:8080/example/中国?name=中国
实际上提交是:
GET /example/%E4%B8%AD%E5%9B%BD?name=%D6%D0%B9%FA
(1) 对于中文IE,如果在高级选项中取消总以UTF-8发送,则PathInfo和QueryString是URL encode按照GBK编码。
实际上提交是:
GET /example/%D6%D0%B9%FA?name=%D6%D0%B9%FA
(3) 对于中文firefox,则pathInfo和queryString都是URL encode按照GBK编码。
实际上提交是:
GET /example/%D6%D0%B9%FA?name=%D6%D0%B9%FA
很显然,不同的浏览器以及同一浏览器的不同设置,会影响最终URL中PathInfo的编码。对于中文的IE和FIREFOX都是采用GBK编码QueryString。
小结:解决方案:
1、URL中如果含有中文等非ASCII字符,则浏览器会对它们进行URLEncode。为了避免浏览器采用了我们不希望的编码,所以最好不要在URL中直接使用非ASCII字符,而采用URL Encode编码过的字符串%.
比如:
URL:http://localhost:8080/example/中国?name=中国
建议:
URL:http://localhost:8080/example/%D6%D0%B9%FA?name=%D6%D0%B9%FA
2、我们建议URL中PathInfo和QueryString采用相同的编码,这样对服务器端处理的时候会更加简单。
2、还有一个问题,我发现很多程序员并不明白URL Encode是需要指定字符集的。不明白的人可以看看这篇文档:http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/net/URLEncoder.html
2、 POST提交
对于POST方式,表单中的参数值对是通过request body发送给服务器,此时浏览器会根据网页的ContentType("text/html; charset=GBK")中指定的编码进行对表单中的数据进行编码,然后发给服务器。
在服务器端的程序中我们可以通过Request.setCharacterEncoding() 设置编码,然后通过request.getParameter获得正确的数据。
解决方案:
1、从最简单,所需代价最小来看,我们对URL以及网页中的编码使用统一的编码对我们来说是比较合适的。
如果不使用统一编码的话,我们就需要在程序中做一些编码转换的事情。这也是我们为什么看到有网络上大量的资料介绍如何对乱码进行处理,其中很多解决方案都只是一时的权宜之计,没有从根本上解决问题。
(二)、Servlet服务器
Servlet服务器实现的Servlet遇到URL和POST提交的数据中含有%的字符串,它会按照指定的字符集解码。下面两个Servlet方法返回的结果都是经过解码的:
request.getParameter("name");
request.getPathInfo();
这里所说的"指定的字符集"是在应用服务器的配置文件中配置。
(1) tomcat服务器
对于tomcat服务器,该文件是server.xml
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="150" connectionTimeout="20000"
redirectPort="8443" URIEncoding="GBK"/>
URIEncoding告诉服务器servlet解码URL时采用的编码。
<Connector port="8080" ... useBodyEncodingForURI="true" />
useBodyEncodingForURI告诉服务器解码URL时候需要采用request body指定的编码。
(2) weblogic服务器
对于weblogic服务器,该文件是weblogic.xml
<input-charset>
<java-charset-name>GBK</java-charset-name>
</input-charset>
(三)浏览器显示
浏览器根据http头中的ContentType("text/html; charset=GBK"),指定的字符集来解码服务器发送过来的字节流。我们可以调用 HttpServletResponse.setContentType()设置http头的ContentType。
总结:
1、URL中的PathInfo和QueryString字符串的编码和解码是由浏览器和应用服务器的配置决定的,我们的程序不能设置,不要期望用request.setCharacterEncoding()方法能设置URL中参数值解码时的字符集。
所以我们建议URL中不要使用中文等非ASCII字符,如果含有非ASCII字符的话要使用URLEncode编码一下,比如:
http://localhost:8080/example1/example/中国
正确的写法:
http://localhost:8080/example1/example/%E4%B8%AD%E5%9B%BD
并且我们建议URL中不要在PathInfo和QueryString同时使用非ASCII字符,比如
http://localhost:8080/example1/example/中国?name=中国
原因很简单:不同浏览器对URL中PathInfo和QueryString编码时采用的字符集不同,但应用服务器对URL通常会采用相同的字符集来解码。
2、我们建议URL中的URL Encode编码的字符集和网页的contentType的字符集采用相同的字符集,这样程序的实现就很简单,不用做复杂的编码转换。
相关推荐
URL编码,全称为统一资源定位符(Uniform Resource Locator)编码,是互联网上用于标识资源的一种标准格式。在HTTP协议中,URL是访问网络资源的重要途径,但有些字符在URL中直接使用时可能会引起问题,因此需要进行...
### JS实现URL编码转换中文 在Web开发过程中,经常需要处理URL中的特殊字符,特别是中文字符。由于URL传输限制及浏览器解析原因,中文等非ASCII字符需要被编码为特定格式才能在网络上传输。本文将详细介绍如何使用...
这个文本文件可能包含了一个示例的C代码或关于URL编码的说明。打开文件,可以找到具体的实现方法或者使用指南。可能包含如下内容: ```c void encodeUrl(char* input, char* output) { // ... } ``` 或者是...
C++作为一门强大的系统级编程语言,虽然没有内置的URL编码和解码函数,但开发者可以借助标准库和第三方库来实现这些功能。本文将深入探讨C++中如何进行URL编码和解码。 URL(Uniform Resource Locator)是互联网上...
关于URL编码和解码的知识点: 1. **URL编码**:URL编码是使用百分号(%)加上字符的ASCII值来表示非ASCII字符或URL中不安全的字符。例如,空格通常被编码为`%20`。 2. **PHP内置函数**:PHP提供了`urlencode()`和`...
标题和描述中提到的“vb url编码解码”是指在Visual Basic(VB)环境中进行URL编码和解码的过程。URL编码,也称为百分号编码,是一种用于将特殊字符转换为适用于URL格式的编码方式,目的是确保这些特殊字符能够正确...
标题中的“URL编码解码小程序”指的是一个工具或软件,其主要功能是处理URL(统一资源定位符)中的编码问题。URL编码是互联网通信中的一种标准化机制,它确保非ASCII字符或特殊字符在URL中能被正确传输和解析。这是...
URL编码,全称为统一资源定位符(Uniform Resource Locator)编码,是互联网上数据通信的一种标准格式,用于确保数据在传输过程中不受损失或错误地被解释。URL编码的主要目的是解决URL中可能包含的特殊字符,如空格...
URL编码,全称为统一资源定位符(Uniform Resource Locator)编码,是互联网上数据通信的一种标准格式,用于将非ASCII字符转换为可以在URL中安全传输的形式。GBK编码是中国大陆广泛使用的汉字编码标准,它包含了GB...
这个名为“一个简单url编码解码”的项目,就是为新手提供了一个理解和实践URL编码与解码机制的实例。 URL编码是根据RFC 3986标准进行的,主要使用百分号(%)表示非ASCII字符或特殊字符的ASCII十六进制值。例如,...
本文将深入探讨“C#自动识别URL编码”的主题,帮助开发者解决URL编码带来的乱码问题。 URL编码,也称为百分号编码(Percent-encoding),是统一资源定位符(Uniform Resource Locator, URL)的一部分,用于在非...
另外,虽然在大多数情况下,URL编码遵循ASCII标准,但在Unicode环境中,URL编码也可以扩展到包含非ASCII字符,这通常被称为“ Punycode”转换。 在实际开发中,了解并正确使用URL编码和解码不仅能保证数据的完整性...
URL编码是互联网上的一种标准编码方式,用于将特殊字符转换为可安全传递的ASCII字符串,以便在URL(统一资源定位符)中使用。这个“URL编码转换工具”就是专门为了帮助开发者解决这个问题而设计的。它能够将URL中的...
### URL编码转换:将URL转换为Unicode进行传输 在互联网技术的应用中,URL(Uniform Resource Locator,统一资源定位符)编码转换是一项基本且重要的技术。本文将深入探讨URL编码转换的相关概念、应用场景以及一个...
自己写的,可能有bug,请大家一块学习 环境为PB12 函数(及参数) 作用 arraysort 对一维数组进行排序 decto 将十进制数字转成其它进制字符串 ...urlencode 将指定字符串以进行指定字符集url编码 涨价了,哈哈
URL编码遵循统一资源标识符(URI)的规则,其中最常用的是基于百分号(%)的编码方法。每个非ASCII或特殊字符会被替换为"%xy"的形式,其中xy是该字符在UTF-8编码中的两个字节的十六进制表示。例如,空格字符(ASCII...
在IT领域,URL编码是一种常见的数据处理技术,特别是在网络编程中。这个压缩包文件的标题和描述提及了“url加密”和“URL编码”,实际上,它们指的是同一个概念,即URL编码(URL Encoding)。URL编码是根据统一资源...
今天写一个POST程序的时候有一段UNICODE字符串需要进行URL编码后进行提交。但是找遍了精易模块和百度都没有说有这这个命令 让Unicode字符串(易语言里面以字节集表示)直接进行正确的URL编码。所以就自己写了一个...