在项目中遇到一个问题,在webveiw和原生之间进行传值的时候,出现了一些encode的小问题。看起来很简单的问题,实际上却存在不小的坑。

首先说一下目前项目的结构,在一个activity中,webview和原生之间有多种交互。

如图所示

在原生调用webview方法,这种协议已经非常常用了,直接调用loadJS();但是自定义协议这个过程,使用的拦截跳转的方式,按照预定的协议来解析数据,这里面就有一些情况,比如数据中出现了中文,webview会encode这部分内容,这就要求我们对拦截以后的内容进行decode。

见下方代码:

   private String decodeUrl(String url) {
try {
return URLDecoder.decode(url, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}

上面这段代码,看上去是很合理的,但是老司机们认真看看,这里面有坑。

首先看一下底层代码的decode。

   /**
* @throws UnsupportedEncodingException if {@code charsetName} is not supported.
*/
public static String decode(String s, String charsetName) throws UnsupportedEncodingException {
return UriCodec.decode(s, true, Charset.forName(charsetName), true);
}

我想老司机们应该已经明白了是为啥了,就是检查异常和运行时异常的问题了。UnsupportedEncodingException 仅仅是检查时异常,而可能还有运行时异常,因此这里代码需要改为:

 private String decodeUrl(String url) {
String decodeUrl = "";
try {
decodeUrl = URLDecoder.decode(url, "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
return decodeUrl;
}
}

这里对异常进行简单的介绍。

在 Java 中,所有的异常都继承了 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。
Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。

。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。

Exception(异常):是程序本身可以处理的异常。见图:

运行时异常很常见比如 空指针、非法参数、数组越界、类转换异常、算术异常等。这些异常需要老司机们有经验有技巧的对待,写代码时动用金手指,把这些异常都捕获住。

常见的比如:

   String  numberStr= "1";
try{
int number = Integer.valueOf(numberStr);
} catch(exception e){
e.printStackTrace();
}

上面代码没有检查时异常,但是需要老司机捕获住。

当然实际上这里面坑还不止这些,中文符号被decode还办好,关键是一些特殊符号不好办。

有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了。编码的格式为:%加字符的ASCII码,即一个百分号%,后面跟对应字符的ASCII(16进制)码值。例如 空格的编码值是"%20"。
下表中列出了一些URL特殊符号及编码。

实际测试中发现,只要替换调%就好了。

替换代码为:

  private String decodeUrl(String url) {
String decodeUrl = "";
try {
String transformUrl = url.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
decodeUrl = URLDecoder.decode(transformUrl,"UTF-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
LogUtil.e("my", "decodeUrl:" + decodeUrl);
return decodeUrl;
}
}

以上代码,通过了表格8种符号 全半角形式以及日文韩文的测试,传值和decode都是正常的。

												

URLencode 特殊字符 转义 遇上的坑的更多相关文章

  1. RowFilter遇上特殊字符*%'[]\

    开发时,时不时需要分析DataView的数据.计算,过滤等 .但是处理的值有可能会遇上是带有特殊字符*.%.'.[.]和\ .需要手动在表达式中,处理这些特殊字符,需要再使用"[" ...

  2. 当DataTable的列名遇上特殊字符"["和"]"时

    刚才有看到一个问题http://bbs.csdn.net/topics/390781072.是在DataTable获取某列最小值,但是在动态生生DataTable时,列名有遇上特特殊字符"[ ...

  3. html特殊字符转义问题(转!)

    html.javascript.url特殊字符转义在实际编程中都是有用到的,有的人对特殊字符转义的使用不是很清楚,下面就对html,javascript,url特殊字符的转义做一下说明和归纳. htm ...

  4. 当@PathVariable遇上中文和点

    当@PathVariable遇上中文和点 Spring MVC从3.0开始支持REST,而主要就是通过@PathVariable来处理请求参数和路径的映射.  由于考虑到SEO的缘故,很多人喜欢把新闻 ...

  5. python正则表达式模块re:正则表达式常用字符、常用可选标志位、group与groups、match、search、sub、split,findall、compile、特殊字符转义

    本文内容: 正则表达式常用字符. 常用可选标志位. group与groups. match. search. sub. split findall. compile 特殊字符转义 一些现实例子 首发时 ...

  6. freemarker特殊字符转义

    一个坑了很久的问题,今天上午终于在同事帮助下搞定了,,利用ibatis框架,从sqlserver数据库中读取数据,放到java对象中,其中有一项description中有特殊字符,没留意,在ftl文件 ...

  7. 前端遇上Go: 静态资源增量更新的新实践

    前端遇上Go: 静态资源增量更新的新实践https://mp.weixin.qq.com/s/hCqQW1F8FngPPGZAisAWUg 前端遇上Go: 静态资源增量更新的新实践 原创: 洋河 美团 ...

  8. 当微信小程序遇上filter~

    在微信小程序的开发过程中,当你想要实现不同页面间的数据绑定,却为此抓耳饶腮时,不妨让微信小程序与filter 来一场完美的邂逅,相信会给你带来别样的惊喜~ 前段时间被安利了一个很实用的公众号-前端早读 ...

  9. html实体编码遇上js代码

    单双引号 在js代码中 在js中单.双引号引起来的是字符串,如果我们要在字符串中使用单.双引号,需要反斜杠进行转义 let str='user\'s name'; // or let str=&quo ...

随机推荐

  1. IOS开发中AVFoundation中AVAudioPlayer的使用

    IOS开发中如何调用音频播放组件 1.与音频相关的头文件等都在AVFoundation.h中,所以第一步是添加音频库文件: #import <AVFoundation/AVFoundation. ...

  2. Outlook 2013 电子邮件账户设置备份与恢复

    与之前版本不同,Outlook 2013需要备份以下注册表内容:HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Profiles恢复时 ...

  3. jquery 中prop()的使用方法

    1:设置input的选中属性:$('.passenger').find('.is-need-tel').prop('checked',true); 2:获取input是否选中: $('.passeng ...

  4. apache的工作模式 和 最大连接数设置

    经过测试 效果明显 (1)首选查看apache的工作模式 windows下的查看apache的工作模式命令:httpd -l 如果列出mod_win32.c,则表示是 win32.c 工作方式. 列出 ...

  5. 如何用C语言封装 C++的类,在 C里面使用

    本文给出了一种方法.基本思想是,写一个 wrapper文件,把 C++类封装起来,对外只提供C语言的接口,和 C++i相关的都在  wrapper的实现文件里实现. 1. apple.h #ifnde ...

  6. jQuery插入节点(移动节点)

    jQuery插入节点(移动节点) <%@ page language="java" import="java.util.*" pageEncoding=& ...

  7. 使用 GitHub, Jekyll 打造自己的免费独立博客

    使用 GitHub, Jekyll 打造自己的免费独立博客 GitHub是一个代码托管网站,现在很多开源项目都放在GitHub上. 利用GitHub,可以让全球各地的程序员们一起协作开发.GitHub ...

  8. 利用谷歌开源工具cAdvisor 结合influxdb存储+Grafana前端展示进行Docker容器的监控

    一.Docker 监控方式 1.利用docker 的 docker stats API 命令: docker stats [容器ID/容器名称] [root@docker ~]# docker sta ...

  9. 递归编译的Makefile的实现

    最近写了一个递归Makefile,目的是既可以实现子模块的单独编译,也可以不做任何修改就和整个程序的整体进行无缝衔接的编译.具体的思路是借助第三方文件,将子模块编译好的.o文件的路径自动写到confi ...

  10. java Runtime类

    public class Test { public static void main(String[] args) throws UnsupportedEncodingException { Run ...