URI编码的URL将“%3D”更改为“%253D”

时间:2011-02-01 01:51:48

标签: java url encoding uri

我无法将URL编码为URI:

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);

这不符合我对以下网址的期望:

传入字符串:

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它似乎对字符串中的%已经做了一些神秘的事情。

这是怎么回事?我在这里做错了什么?

4 个答案:

答案 0 :(得分:27)

您首先将(已经转义的)字符串放入URL类。这并没有逃脱任何事情。然后你拉出URL的部分,它们返回它们而不进行任何进一步的处理(所以 - 它们仍然被转义,因为当你把它们放入时它们被转义)。最后,您将使用multi-argument constructor将这些部分放入URI课程。此构造函数被指定为使用百分比对URI组件进行编码。

因此,在最后一步中,例如,“:”变为“%3A”(好),“%3A”变为“%253A” (坏)。由于您要输入已编码*的URL,因此您不希望再次对它们进行编码。

因此,URI的{​​{3}}是您的朋友。它不会逃避任何事情,并要求您传递预转义字符串。因此,您根本不需要URL

mUrl = "A string url is already percent-encoded for use in a new HttpGet()";
URI uri = new URI(mUrl);

*唯一的问题是,如果您的网址有时不是百分比编码的,有时它们是。然后你有一个更大的问题。您需要确定您的程序是从一个始终编码的URL开始,还是需要编码的URL。

请注意,没有这样的东西是一个完整的URL,不是百分比编码的。例如,您无法获取完整的网址“http://example.com/bob&co”,并以某种方式将其转换为正确编码的网址“http://example.com/bob%26co” - 您如何区分语法(哪个不应该' t被转义)和字符(应该)?这就是URI的单参数形式要求字符串已经转义的原因。如果您有未转义的字符串,则需要在插入到完整的URL语法之前对它们进行百分比编码,这就是URI的多参数构造函数可以帮助您完成的。

编辑:我错过了原始代码丢弃片段的事实。如果要删除URL的片段(或任何其他部分),可以按上述方式构建URI,然后根据需要拉出所有部分(它们将被解码成常规字符串),然后将它们传递回URI多参数构造函数(它们将作为URI组件重新编码):

uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
              uri.getPath(), uri.getQuery(), null)  // Remove fragment

答案 1 :(得分:4)

URL类在解析URL时没有解码%-sequences,但URI类正在对它们进行编码(再次)。使用URI解析网址字符串。

的Javadoc:

http://download.oracle.com/javase/6/docs/api/java/net/URL.html

  

根据RFC2396中定义的转义机制,URL类本身不会对任何URL组件进行编码或解码 。调用者负责编码任何字段,这些字段需要在调用URL之前进行转义,并且还要解码从URL返回的任何转义字段。此外,由于URL不知道URL转义,因此它无法识别相同URL的编码或解码形式之间的等效性。例如,两个网址:

http://foo.com/hello world/ and http://foo.com/hello%20world
  

将被视为彼此不相等。   注意,URI类确实在某些情况下执行其组件字段的转义。

     

管理URL编码和解码的推荐方法是使用URI ,并使用toURI()和URI.toURL()在这两个类之间进行转换

答案 2 :(得分:4)

%3d 表示 - > = (等于)

并且

%253D - > = (等于)十进制6hex(字节)3D

%253D 十六进制指示符 对于CGI:%3D

答案 3 :(得分:-2)

这里发生的事情是第一个网址中的%个符号正在转义,这意味着它们会在输出中变为%25。您需要采取预防措施,以便您的脚本只能转义字母数字字符以及一些符号 - 但已转义字符。

这些是需要逃避的角色:

<
>
"
!
#
$
'
(
)
*
,
-
.
/
:
;
@
[
\
]
^
_
`
{
|
}
~

其余内容,如=%&以及字母数字字符,则不会。