如何创建含&值的查询参数的java.net.URI实例?
解决URI构造时参数值含&符号的转义问题
我使用java.net.URI的多参数构造函数构建URI时遇到了问题:当查询参数foo的值包含空格和&符号时,直接传入未处理的字符串:
(new java.net.URI "https" "foobar.net" "/" "foo= hello&bye " nil )
构造函数会把&识别为参数分隔符,最终生成的URI里出现了两个参数:
#object[java.net.URI 0x3b809711 "https://foobar.net/?foo=%20hello&bye%20"]
如果手动把&转义成%26再传入:
user=> (new java.net.URI "https" "foobar.net" "/" "foo= hello%26bye " nil )
构造函数又会对%进行二次转义,得到双重编码的结果:
#object[java.net.URI 0x5c84624f "https://foobar.net/?foo=%20hello%2526bye%20"]
解决方法
不要手动转义参数值,而是先通过java.net.URLEncoder对参数值单独进行URL编码,再拼接成查询字符串传入构造函数。这样既能正确转义参数值里的特殊字符,又不会触发构造函数的二次转义。
代码示例:
(let [param-value " hello&bye " ; 对参数值进行UTF-8编码 encoded-value (java.net.URLEncoder/encode param-value "UTF-8") query-string (str "foo=" encoded-value)] (new java.net.URI "https" "foobar.net" "/" query-string nil))
执行后会生成符合预期的URI:
#object[java.net.URI 0x12345678 "https://foobar.net/?foo=%20hello%26bye%20"]
原理说明
URI的多参数构造函数会自动转义查询字符串中的非法字符,但&作为参数分隔符属于合法字符,不会被转义;而手动输入的%会被识别为普通字符,进而被转义成%25。使用URLEncoder编码参数值后,特殊字符会被转换成标准的URL编码格式,构造函数会直接保留这些编码结果,不会再进行二次处理。
内容的提问来源于stack exchange,提问作者Michiel Borkent
相关产品推荐
相关产品推荐

