android实现url编码:从踩坑到顺手

在Android应用里拼接请求参数、生成分享链接或处理WebView回调时,URL编码几乎躲不开。但Java和Android提供的编码方式不止一种,用错方法会导致空格变加号、中文变乱码、参数被截断。这篇文章从实际场景出发,帮你理清android实现url编码的步骤和容易忽略的细节。

在线工具URL编码

先搞清楚:你要编码的是哪一部分

URL编码不是把整个链接丢进编码器。一个完整的URL里,协议、域名、路径、查询参数各有各的规则。查询参数的值需要编码,参数名一般也要,但分隔符&和=不能编码。路径段里的空格和中文需要处理,而协议和域名通常不需要。

动手前先明确:你是在拼接查询字符串,还是在编码一个完整的回调地址?前者只编码参数值,后者要把整个地址作为参数值再编码一次。这个区别决定了后面选哪个方法。

Android里常用的两种编码方式

最直接的是URLEncoder.encode(String, String),它来自Java标准库,Android全版本可用。注意它遵循的是application/x-www-form-urlencoded规则,会把空格编码成+,而不是%20。如果你的服务端按标准URL解析,+可能被当成加号本身,需要额外处理。

另一种是Uri.encode(String),这是Android特有的方法。它不会把空格变成+,而是编码成%20,更接近RFC 3986的预期。但它对某些字符的处理和URLEncoder不同,比如~、!、*等。选择哪种取决于你的使用场景:表单提交用前者,拼接URL路径或查询参数用后者更稳妥。

如果只是临时验证编码结果,可以用URL编码工具快速对比,避免在代码里反复试错。

分步操作:在代码里正确编码一个参数

假设你要把用户输入的关键词拼到搜索接口后面。

第一步,拿到原始字符串,确认它不包含首尾空格(如果有,先trim,否则编码后空格会保留)。

第二步,选择编码方法。如果服务端明确要求application/x-www-form-urlencoded,用URLEncoder.encode(keyword, "UTF-8");如果只是拼URL,用Uri.encode(keyword)。

第三步,处理编码结果中的+。如果用了URLEncoder且服务端不接受+表示空格,把结果里的+替换成%20。

第四步,拼接完整URL。注意不要在编码后的值上再次调用编码方法,否则百分号会被二次编码成%25。

第五步,用Uri.parse或HttpURLConnection发起请求前,打印完整URL检查一遍,确认参数值没有多余的分隔符。

中文与特殊字符:容易翻车的地方

中文在URL里必须转成UTF-8字节再百分号编码。URLEncoder和Uri.encode默认都按UTF-8处理,但如果你传入的字符串来自旧系统或文件,编码可能不是UTF-8,这时需要先转码。

另一个坑是+和%20的混用。有些服务端框架会自动把+解码成空格,有些不会。如果发现参数值里的空格变成了加号,或者加号变成了空格,先检查编码方法和服务端解码规则是否匹配。

还有斜杠/和问号?。在查询参数值里,这两个字符必须编码,否则会被解析成路径分隔符或新的查询起点。Uri.encode默认会编码它们,但URLEncoder也会,所以问题不大。真正要小心的是你自己手动拼接时漏掉了编码。

关于中文场景的更细讨论,可以参考android中文url编码转换:常见误区与处理思路和android中文转url编码:常见场景与处理要点。

排查清单:编码后请求还是不对怎么办

先看完整URL。把拼接好的URL打印出来,逐段对照:协议、域名、路径、参数名、参数值。常见问题是参数值里混入了未编码的&或=,导致参数被截断。

再看编码方法是否统一。同一个请求里,有的参数用URLEncoder,有的用Uri.encode,可能导致空格表示不一致。统一成一种,或者统一做后处理。

然后检查是否重复编码。如果参数值来自另一个已经编码过的URL,再编码一次就会得到%25开头的序列。解码一次看看原始值是什么。

最后确认服务端解码方式。有些服务端只认%20,有些对+也兼容。如果无法改服务端,就在客户端把+替换掉。

总结

android实现url编码的关键是选对方法、只编码该编码的部分、避免二次编码。先明确编码对象是参数值还是完整地址,再在 URLEncoder 和 Uri.encode 之间做选择,最后检查完整 URL 和服务端解码规则。遇到中文或特殊字符时,统一字符集并留意加号与空格的转换。

相关文章

常见问题

Q1URLEncoder.encode 和 Uri.encode 到底选哪个?

如果是在拼查询字符串且服务端按表单规则解码,用 URLEncoder;如果是在拼 URL 路径或希望空格编码成 %20,用 Uri.encode。不确定时优先 Uri.encode,再根据服务端反馈调整。

Q2为什么编码后的中文变成了乱码?

多半是原始字符串的字符集不是 UTF-8,或者编码时指定的字符集与服务端不一致。确保编码方法第二个参数传 "UTF-8",并检查数据来源的编码。

Q3参数值里的加号被解码成空格了怎么办?

这是 application/x-www-form-urlencoded 的规则:加号表示空格。如果加号是数据的一部分,编码前先把加号替换成 %2B,或者改用 Uri.encode 并确认服务端支持。

Q4整个回调地址作为参数时怎么编码?

把回调地址当作普通字符串,用选定的方法编码一次,然后拼到外层 URL 的参数值位置。不要先编码内层再编码外层,否则会二次编码。