URI编码的URL将“%3D”更改为“%253D”
我在编写URI的URL时遇到问题:
mUrl = "A string url that needs to be encoded for use in a new HttpGet()"; URL url = new URL(mUrl); URI uri = new URI(url.getProtocol(), url.getAuthority(), url.getPath(), url.getQuery(), null);
这不符合我对以下URL的期望:
传入字符串:
http://m.bloomingdales.com/img?url=http%3A%2F%2Fimages.bloomingdales.com%2Fis%2Fimage%2FBLM%2Fproducts%2F3%2Foptimized%2F1140443_fpx.tif%3Fwid%3D52%26qlt%3D90% 2C0%26layer%3Dcomp%26op_sharpen%3D0%26resMode%3Dsharp2%26op_usm%3D0.7%2C1.0%2C0.5%2C0%26fmt%3Djpeg&TTL = 30D
出来是:
http://m.bloomingdales.com/img?url=http%253A%252F%252Fimages.bloomingdales.com%252Fis%252Fimage%252FBLM%252Fproducts%252F3%252Foptimized%252F1140443_fpx.tif%253Fwid%253D52%2526qlt%253D90% 252C0%2526layer%253Dcomp%2526op_sharpen%253D0%2526resMode%253Dsharp2%2526op_usm%253D0.7%252C1.0%252C0.5%252C0%2526fmt%253Djpeg&TTL = 30D
哪个坏了。 例如, %3D
变成%253D
它似乎对字符串中的%已经做了一些神秘的事情。
发生了什么事,我在这里做错了什么?
您首先将(已经转义的)字符串放入URL
类中。 这并没有逃脱任何事情。 然后你将拉出URL
各个部分,这些部分返回它们而不进行任何进一步的处理(因此 – 它们仍然被转义,因为当你把它们放入时它们被转义)。 最后,使用多参数构造函数将这些部分放入URI
类中。 此构造函数被指定为使用百分比对URI组件进行编码。
因此,在该最后步骤中,例如,“ :
”变为“ %3A
”(好),“ %3A
”变为“ %253A
”(差)。 由于您要放入已编码*的URL,因此您不希望再次对它们进行编码。
因此, URI
的单参数构造函数是您的朋友。 它不会逃避任何事情,并要求您传递预先转义的字符串。 因此,您根本不需要URL
:
mUrl = "A string url is already percent-encoded for use in a new HttpGet()"; URI uri = new URI(mUrl);
*唯一的问题是,如果您的url有时不是百分比编码的,有时它们是。 那你有一个更大的问题。 您需要确定您的程序是从一个始终编码的URL开始,还是需要编码的URL。
请注意,不存在未进行百分比编码的完整URL。 例如,您无法获取完整的url“ http://example.com/bob&co
”并以某种方式将其转换为正确编码的url“ http://example.com/bob%26co
” – 您怎么能告诉语法(不应该被转义)和字符(应该)之间的区别? 这就是URI
的单参数forms要求字符串已经转义的原因。 如果你有非转义字符串,你需要在将它们插入完整的URL语法之前对它们进行百分比编码,这就是URI
的多参数构造函数可以帮助你做的事情。
编辑:我错过了原始代码丢弃片段的事实。 如果要删除URL的片段(或任何其他部分),可以按上述方式构造URI
,然后根据需要拉出所有部分(它们将被解码为常规字符串),然后将它们传递回URI
多参数构造函数(它们将被重新编码为URI组件):
uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), null) // Remove fragment
URL
类在解析URL时没有解码%-sequences,但URI
类正在对它们进行编码(再次)。 使用URI
来解析URL字符串。
的Javadoc:
http://download.oracle.com/javase/6/docs/api/java/net/URL.html
URL类本身不会根据RFC2396中定义的转义机制对任何URL组件进行编码或解码 。 调用者负责编码在调用URL之前需要转义的任何字段,以及解码从URL返回的任何转义字段。 此外,由于URL不了解URL转义,因此它无法识别同一URL的编码或解码forms之间的等效性。 例如,两个url:
http://foo.com/hello world/ and http://foo.com/hello%20world
被认为不相等。 注意,URI类确实在某些情况下执行其组件字段的转义。
管理URL编码和解码的推荐方法是使用URI ,并使用toURI()和URI.toURL()在这两个类之间进行转换。
%3d表示 – > = (等于)
和
%253D – > = (等于)十进制6hex(字节)3D
CGI的%253Dhex指示符: %3D
这里发生的是来自第一个URL的%
符号被转义,这意味着它们在输出中变为%25
。 您需要采取预防措施,以便您的脚本只能转义字母数字字符,以及一些符号 – 但尚未转义字符。
这些是需要逃避的一些角色:
< > " ! # $ ' ( ) * , - . / : ; @ [ \ ] ^ _ ` { | } ~
其余的,如=
, %
和&
,以及字母数字字符,则不会。