文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android中URLEncoder空格被转码为"+"号的处理办法

2023-01-09 15:00

关注

Android前段和后端接口进行交互时,经常会遇到特殊字符,比如表情、特殊标点等,这样在Url中是无法识别的,需要进行转码,后端进行解码交互。

但当使用URLEncoder时,会发现字符串中的空格被转换成“+”号,如果编码后的内容入库后,将导致读取时,前段本来是空格的地方,会显示成“+”号字符。

到底为什么会这样,我们还是看看源码的实现。

首选,URLEncoder中定义了哪些字符不可以被转码。

static BitSet dontNeedEncoding;

dontNeedEncoding中就包含了不允许转码的字符集合,只有在这里面能找不到的字符才会被正常转码。下面是dontNeedEncoding初始化过程

static {
    //创建一个容量为256的位集合
    dontNeedEncoding = new BitSet(256);
    int i;
    //循环a-z,将其字符值(不是字符串值)存入
    for (i = 'a'; i <= 'z'; i++) {
        dontNeedEncoding.set(i);
    }
    //同上
    for (i = 'A'; i <= 'Z'; i++) {
        dontNeedEncoding.set(i);
    }
    //同上
    for (i = '0'; i <= '9'; i++) {
        dontNeedEncoding.set(i);
    }
    //在这个地方,官方特意做了说明
    //空格将被编码为加号
    dontNeedEncoding.set(' '); 
    dontNeedEncoding.set('-');
    dontNeedEncoding.set('_');
    dontNeedEncoding.set('.');
    dontNeedEncoding.set('*');
    //默认编码格式
    dfltEncName = AccessController.doPrivileged(
        new GetPropertyAction("file.encoding")
    );
}

上面的代码我们看到,除了英文字母,数字和几个能识别的字符外,都需要转码。

我们再来看看encode方法。

public static String encode(String s, String enc)
    throws UnsupportedEncodingException {
//标记是否有字符被转码了,如果没有,就直接返回原始字符串
//如果有,就返回out的结果
    boolean needToChange = false;
    //存放转码后的结果
    StringBuffer out = new StringBuffer(s.length());
    Charset charset;
    CharArrayWriter charArrayWriter = new CharArrayWriter();
//如果未指定编码,抛出异常
    if (enc == null)
        throw new NullPointerException("charsetName");
 
    try {
        charset = Charset.forName(enc);
    } catch (IllegalCharsetNameException e) {
        throw new UnsupportedEncodingException(enc);
    } catch (UnsupportedCharsetException e) {
        throw new UnsupportedEncodingException(enc);
    }
//遍历要编码的字符串
    for (int i = 0; i < s.length();) {
        //取出指定位置的字符
        int c = (int) s.charAt(i);
        if (dontNeedEncoding.get(c)) {
            //这里,判断如果字符是空格,就转为“+”
            if (c == ' ') {
                c = '+';
                needToChange = true;
            }
            out.append((char)c);
            i++;
        } else {
            // convert to external encoding before hex conversion
            do {
                charArrayWriter.write(c);
                
                if (c >= 0xD800 && c <= 0xDBFF) {
                    ......
                }
                i++;
            } while (i < s.length() && !dontNeedEncoding.get((c = (int) s.charAt(i))));
 
            charArrayWriter.flush();
            String str = new String(charArrayWriter.toCharArray());
            byte[] ba = str.getBytes(charset);
            for (int j = 0; j < ba.length; j++) {
                //添加百分号,比如a'a转为a%27a
                out.append('%');
                ......
            }
            charArrayWriter.reset();
            needToChange = true;
        }
    }
 
    return (needToChange? out.toString() : s);
}

我们讨论的问题,就是下面这几行。

那么如何处理该问题呢?

注意:网上那种替换空格或加号的方法是不可行的,因为可能会替换掉正常的空格和加号。

建议自己仿照官方的代码,写一套自己转码和解码过程,这个不难的。或者找第三方的(比如spring提供的 UriUtils )。

另外,Android提供了Uri.encode,虽然可以正常转码空格,但是它不需要转换的字符和URLEncode有一点差别,大家在用的时候,根据情况选择即可。

下面是Uri.encode中不会被转码的字符

    
    private static boolean isAllowed(char c, String allow) {
        return (c >= 'A' && c <= 'Z')
                || (c >= 'a' && c <= 'z')
                || (c >= '0' && c <= '9')
                || "_-!.~'()*".indexOf(c) != NOT_FOUND
                || (allow != null && allow.indexOf(c) != NOT_FOUND);
    }

总结

到此这篇关于Android中URLEncoder空格被转码为"+"号的处理办法的文章就介绍到这了,更多相关Android URLEncoder空格被转码+号内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯