本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看活动链接
问题描述
如果是我有一个链接
http://example.com/query?q=
我有一个用户输入的查询,如:
random word £500 bank $
我希望结果是一个正确编码的URL:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
实现这一目标的最佳方式是什么?我尝试了URLEncoder
并创建URI/URL对象,但其中都没有完全正确的。
部分高赞回答
最高赞回答(1227赞)
URLEncoder
是实现的方法。只需要记住,只需编码单个查询字符串参数名称或值,而不是整个URL,这是为了确保不是查询字符串参数分隔符字符&
,也不是参数名称———值分隔符=
。
String q = "random word £500 bank $";
String url = "https://example.com?q=" + URLEncoder.encode(q, StandardCharsets.UTF_8);
当你还是不能在Java 10或更高版本,然后使用StandardCharsets.UTF_8.toString()
作为字符集参数,或者当你还是不能在Java 7或更高版本,然后使用`"UTF-8"。
请注意,查询参数中合法有效的空格要用+
表示,而不是%20
表示。 %20
通常用于表示URI本身中的空格(URI查询字符串分隔字符前的部分?
),而不在查询字符串中(?
零件之后)。
另外请注意,有三种encode()
的方法。一个没有Charset
作为第二个参数,另一个用String
作为第二个抛出检查异常的参数。不推荐使用Charset
参数的那个。切勿使用它并始终指定Charset
参数。Java文档甚至明确建议使用RFC3986和W3C所规定的UTF-8编码。
所有其他字符都不安全,首先使用一些编码方案转换为一个或多个字节。然后,每个字节由3字符串"%xy"表示,其中xy是字节的两位十六进制表示。推荐的使用编码方案是UTF-8。但是,出于兼容性原因,如果未指定编码,则使用该平台的默认编码。
也可以看看这篇文章《每个Web开发人员必须知道URL编码》
第二高赞回答(189赞)
我不会使用URLEncoder
。除了被命名错误(URLEncoder
与URL无关)、效率低(它使用了一个StringBuffer
而不是Builder,并进行了几个慢速的其他事情),它也很容易搞砸。
相反,我将使用URIBuilder
或Spring
的org.springframework.web.util.UriUtils.encodeQuery
或者共同性Apache HttpClient,原因是你必须以不同的方式转义查询参数名称(即BalusC的答案q
)和参数值。
示例代码:
import org.apache.http.client.utils.URIBuilder;
URIBuilder ub = new URIBuilder("http://example.com/query");
ub.addParameter("q", "random word £500 bank \$");
String url = ub.toString();
// Result: http://example.com/query?q=random+word+%C2%A3500+bank+%24
本文翻译自Stack Overflow。关于翻译文章,聆风也相对生疏,难免有错漏,欢迎各位大佬在评论区批评指正,谢谢!