java GET 请求参数含有特殊字符


有这样一件怪事,
android 2.1 使用 url.openConnection 提交一个 get 请求到服务器
其中的参数含有 % 特殊字符,并未处理即可发送到服务端,并接收处理

在 android 4.x 使用同样的代码,则会抛出异常,如下:

   
  12-10 09:47:21.459: W/System.err(5899): java.io.IOException: java.net.URISyntaxException: Invalid % sequence: %5m in query at index 66: http://192.168.1.55/request.php?passwd=nE7jA%5m
  
12-10 09:47:21.459: W/System.err(5899): at libcore.net.http.HttpEngine.<init>(HttpEngine.java:194)
12-10 09:47:21.459: W/System.err(5899): at libcore.net.http.HttpURLConnectionImpl.newHttpEngine(HttpURLConnectionImpl.java:256)
12-10 09:47:21.459: W/System.err(5899): at libcore.net.http.HttpURLConnectionImpl.initHttpEngine(HttpURLConnectionImpl.java:243)
12-10 09:47:21.469: W/System.err(5899): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:78)
12-10 09:47:21.469: W/System.err(5899): at todo$SendGetRequest.run(todo.java:460)
12-10 09:47:21.469: W/System.err(5899): at java.lang.Thread.run(Thread.java:856)
12-10 09:47:21.469: W/System.err(5899): Caused by: java.net.URISyntaxException: Invalid % sequence: %5m in query at index 66: http://192.168.1.55/request.php?passwd=nE7jA%5m
12-10 09:47:21.479: W/System.err(5899): at libcore.net.UriCodec.validate(UriCodec.java:58)
12-10 09:47:21.479: W/System.err(5899): at java.net.URI.parseURI(URI.java:406)
12-10 09:47:21.479: W/System.err(5899): at java.net.URI.<init>(URI.java:204)
12-10 09:47:21.479: W/System.err(5899): at java.net.URL.toURILenient(URL.java:510)
12-10 09:47:21.479: W/System.err(5899): at libcore.net.http.HttpEngine.<init>(HttpEngine.java:192)
12-10 09:47:21.489: W/System.err(5899): ... 5 more

在网上差了下,使用 URL 对象生成 URI 再使用 httpClient 发送可以解决异常
但是在接收的时候,服务端认为字符串不匹配,
ps: 服务端是一个不可修改的终端,无法调试

我用 php 做了个 $_REQUEST 接收并写入文件的操作,
通过 tail 读文件发现发送过去的参数是没有问题的,% 也没有被转义成 16进制
为何服务端接收后会认为参数不正确呢?

更新:
测试用例:
用 2.1 的 Android 跑应用,直接(url.openConnection)访问可以正常使用
用 4.x 的 Android 跑应用,使用 httpClient + URI / URLEncode 发送都失败
用 wget 直接发送 get 请求,失败
用 chrome 在浏览器上面发送 get 请求,正常

再一次更新:
得知 服务端读取的 参数 并没有 URLDecode 就拿去做字符串比对了
这样的话,如果可以只发送一个单纯的 % 字符,而非被转义的 %25 呢?

我应该如何让 4.x 的 Android 直接发送 % 字符,而且不会抛异常呢?

原始的连接代码

请输入图片描述

java Android php

hea7ven 10 years, 8 months ago

Your Answer