java.net.URI和查询参数值中的百分比
结果是java.net.URI和查询参数值中的百分比,java,encoding,uri,percent-encoding,Java,Encoding,Uri,Percent Encoding,结果是http://example.com/servlet?a=x%2520y,其中查询参数值与提供的值不同。奇怪,但这确实遵循Javadoc: “这些构造函数总是引用百分比字符(“%”)。” 我们可以传递解码的字符串,a=xy,然后我们得到一个合理的(?)结果a=x%20y 但是如果查询参数值包含一个“&”字符怎么办?例如,如果该值是带有查询参数的URL本身,则会发生这种情况。查看此(错误)查询字符串: a=b&c。必须在此处转义符号(a=b%26c),否则可以将其视为查询参数a=b和一些垃圾
http://example.com/servlet?a=x%2520y
,其中查询参数值与提供的值不同。奇怪,但这确实遵循Javadoc:
“这些构造函数总是引用百分比字符(“%”)。”
我们可以传递解码的字符串,a=xy
,然后我们得到一个合理的(?)结果a=x%20y
但是如果查询参数值包含一个“&”字符怎么办?例如,如果该值是带有查询参数的URL本身,则会发生这种情况。查看此(错误)查询字符串:
a=b&c
。必须在此处转义符号(a=b%26c
),否则可以将其视为查询参数a=b
和一些垃圾(c
)。如果我将其传递给URI构造函数,它将对其进行编码,并返回错误的URL:…?a=b%2526c
这个问题似乎使java.util.URI变得无用。我是不是遗漏了什么
答覆摘要
java.net.URI确实知道URI的查询部分的存在,但它不了解查询部分的内部结构,每个方案的内部结构可能不同。例如,java.net.URI不理解HTTP查询部分的内部结构。如果java.net.URI将查询视为不透明字符串,并且不改变它,那么这就不会是一个问题。但它尝试应用一些通用的百分比编码算法,这会破坏HTTP URL
因此,我无法使用URI类从其各个部分可靠地组装URL,尽管它有构造函数。我还要提到的是,在Java7中,relativize操作的实现非常有限,仅当一个URL是另一个URL的前缀时才起作用。这两个功能(以及用于这些目的的更精简的接口)是我对java.net.URI感兴趣的原因,但它们都不适合我
最后,我使用java.net.URL进行解析,并编写代码从各个部分组装一个URL,并将两个URL相对化。我还检查了Apache HttpClient URIBuilder类,虽然它确实了解HTTP查询字符串的内部结构,但从4.3开始,在处理整个查询部分时,它与java.net.URI一样存在编码问题。使用
URLEncoder.encode()
方法,例如:
System.out.println(
new URI("http", "example.com", "/servlet", "a=x%20y", null));
query = *uric
查询字符串
URLEncoder.encode("a=x%20y", "ISO-8859-1");
URI中没有错误。
查询组件是一个信息字符串,由
资源。
a=b&c
在查询组件中,字符“;”、“/”、“?”、“:”、“@”、“&”、“=”、“+”、“、”和“$”是保留的 查询字符串中的字符
&
非常有效(表示保留字符、标记字符和字母数字字符)。RFC还声明
许多URI包含由、某些组成或分隔的组件
特殊字符。这些字符称为“保留”,因为
它们在URI组件中的使用仅限于保留的
目的如果URI组件的数据与
保留目的,则冲突数据必须在
正在形成URI。
a=b&c
由于&
有效但保留,因此由用户决定是否对其进行编码
您所称的查询参数不是URI的特性,因此URI
类没有理由(也不应该)支持它
相关的:
我找到的唯一解决方法是使用单参数构造函数和方法。请注意,必须使用URI#getRawQuery()
来避免解码%26
。例如:
System.out.println(
new URI("http", "example.com", "/servlet", "a=x%20y", null));
query = *uric
我所知道的唯一可行的解决方案是反射(参见)
我会使用一些java.net.URI特定的特性:带有查询和权限参数的构造函数以及relativize操作。是的,a=b&c
在语法上是有效的,但它并不意味着明显的意图:一个名为a
的查询参数,其值为b&c
。符号必须转义,但than URI在toString()中返回一个混乱的URL。让我们看一个更现实的例子,我们在return
参数中传递一个相对URLmypage?hello=world
。完整有效的URL是:http://example.com/some?return=mypage%3Fhello%3Dworld
。我应该在java.net.URI多参数构造函数中传递什么才能返回完整的URL?@HontváriJózsefLevente查询参数在HTTP上下文中是相关的。但URI不仅与HTTP上下文相关。查询参数由HTTP服务器解释。在URI中,它们没有任何意义,因此您将无法对URI
类进行任何特殊格式化。java.net.URI不必理解查询部分的内部内容。例如,如果它的多参数构造函数不改变我传递给它们的完全有效的查询字符串就足够了。@HontváriJózsefLevente您传递给它的是哪个完全有效的查询字符串,它改变了它<代码>a=x%20y
不是有效的查询字符串。请注意,RFC声明在正常情况下,URI中的八位字节进行百分比编码的唯一时间是在从其组成部分生成URI的过程中。因此a=x%20y
变为a=x%2520y
。javadoc声明,除了一些小的偏差外,java.net.URI
实例表示URI引用。&
可以是查询组件中的分隔符和数据字符。在后一种情况下,必须对其进行百分比编码。因为URI不理解查询组件的内部结构,所以它无法确定符号是分隔符还是数据字符。因此,正如您所写的,由用户(即我的代码)决定使用哪一种。现在,如果我对符号进行百分比编码,它不是分隔符而是数据字符,那么URI.toString()将返回一个错误的字符串。我是