【专业技术】Android webkit处理汉字编码问题

在XX项目中解决android webkit处理汉字编码问题的总结

1.问题:

服务器通过302重定向方式发送给客户端重定向地址,地址中的汉字采用原数据方式发送,没有经过任何编码。因为其中存在汉字,所以在android端经过webkit解码编码之后,最终无法正常在服务器端请求正确数据。Android中默认使用utf-8编码。

2.分析:

Android在framework中解析http信息,Request.java的函数readResponse通过AndroidHttpClientConnection.java的函数parseResponseHeader解析response的header部分。

存储数据使用的是org.apache.http.util.CharArrayBuffer中的CharArrayBuffer。使用SessionInputBuffer的readline来读取一行,进行解析。

我们主要关心的是Location部分,因为重定向主要是通过Location的值重新去请求url。Android中也是这么做的,不会去html的body中解析标记A的herf。

读取的每一行都会被传入到Headers.java中进行解析。Location地址被转换为String存储到mHeaders[IDX_LOCATION]中。

在从CharArrayBuffer变成String的时候,有个值得注意的地方,通过String的源码可以看到,如果使用char[]的方式传入给String构造参数,String中不会再次编码(encode),而使用byte[]方式传入的话,会经过编码转化以后存储到String的value中。默认编码方式是utf-8.我们这里的CharArrayBuffer里面为char[]方式,所以直接存储,不会经过编码。

Android会将得到的Location地址存储在Header的String数组中。

Request.java的函数readResponse会在最后调用LoadListener的endData结束解析。

在endData中经过一系列的消息转发之后最终走到doRedirect中,从字面意思也能看出来是重定向。从之前存储的Header中取出Location,然后调用native接口将url传送到webcore jni中调用底层进行url解析。将重新解析过的url返回到java层,最后进行http请求。

3.原因:

问题出在jni中进行解析部分。WebCoreResourceLoader的RedirectedToUrl拿到url后会构造KURL对象,KURL在构造函数中经过init,会进行相应的编码,默认编码方式为utf-8。所以汉字的元数据经过这次编码后变为utf-8编码。返回到java部分进行http请求,所以在抓包中出现的%C2%BA%C3%BA%C3%91%C3%A5%C2%B1%C3%B3是“胡彦斌”的元数据0xba, 0xfa,0xd1, 0xe5, 0xb1, 0xf3经过utf-8编码后的结果。

服务器默认的编码应该是gb2312。所以我们发送给服务器后,服务器将按照gb2312去解析,所以就会出现乱码:潞煤�氓卤贸

4.修改方法:

对整个已经经过utf-8编码的url进行utf-8解码。在KURL中有现成的解码函数,默认解码方式为utf-8.:decodeURLEscapeSequences(String)

基于android4.0

注:webkit中的网络模块为libcurl,android中使用的是自己的网络模块,framework中。

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-05-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏帅小子的日常

freemarker的使用

32511
来自专栏MasiMaro 的技术博文

ghost.py在代用JavaScript时的超时问题

在写爬虫的时候,关于JavaScript的解析问题,我在网上找到的一个解决方案是使用ghost.py这个模块,他是一个基于webkit封装的一个客户端,可以用来...

602
来自专栏程序员的SOD蜜

在SQLMAP中使用动态SQL

最近有几个同事和朋友询问如何在SQLMAP中“拼接字符串”,因为有时候条件的数量不固定,条件参数类型也不固定,无法写出 @参数名 这样的SQL语句,也就是大家常...

2039
来自专栏Rgc

python更新数据库脚本两种方法

最近项目的两次版本迭代中,根据业务需求的变化,需要对数据库进行更新,两次分别使用了不同的方式进行更新。 第一种:使用python的MySQLdb模块利用原生的s...

3497
来自专栏决胜机器学习

《Redis设计与实现》读书笔记(十八) ——Redis客户端属性设计与原理

《Redis设计与实现》读书笔记(十八) ——Redis客户端属性设计与原理 (原创内容,转载请注明来源,谢谢) 一、概述 redis服务器是...

2684
来自专栏zhisheng

Windows 64位下安装Redis超详细教程

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(...

32612
来自专栏Porschev[钟慰]的专栏

Nodejs学习笔记(十四)— Mongoose介绍和入门

简介   Mongoose是在node.js异步环境下对mongodb进行便捷操作的对象模型工具   那么要使用它,首先你得装上node.js和mongodb,...

3516
来自专栏Pythonista

python操作redis

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(...

571
来自专栏张善友的专栏

IBatisNet配置

结合上面示例中的IbatisNet配置文件,下面对配置文件中各节点的说明: <?xml version="1.0" encoding="utf-8"?> <s...

1707
来自专栏清风

MySQL数据库 原

其中“/yourpath/crontab_mysql.sql”为需要执行的sql语句。

713

扫描关注云+社区