打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
通过 URL 传递 base64 编码参数的问题,及其解决方案 java代码
通过 URL 传递 base64 编码参数的问题,及其解决方案 java代码

一般情况下,URL 中的参数应使用 url 编码规则,即把参数字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。但是对于带有中文的参数来说,这种编码会使编码后的字符串变得很长。如果希望有短一点的方式对参数编码,可以采用 base64 编码方式对字符串进行编码,但是 base64 编码方式不能处理 JavaScript 中的中文,因为 JavaScript 中的中文都是以 UTF-16 方式保存的。而 base64 只能处理单字节字符,所以不能直接用 base64 对带有中文的 JavaScript 字符串进行编码。但是可以通过 utf.js 这个程序中提供的 utf16to8 来将 UTF-16 编码的中文先转化为 UTF-8 方式,然后再进行 base64 编码。这样编码后的字符串,在传递到服务器端后可以直接通过 base64_decode 解码成 UTF-8 的中文字符串。但是还有个问题需要注意。base64 编码中使用了加号(+),而 + 在 URL 传递时会被当成空格,因此必须要将 base64 编码后的字符串中的加号替换成 %2B 才能当作 URL 参数进行传递。否则在服务器端解码后就会出错。

原来在编写 PHPRPC 1.1 的 JavaScript 客户端实现时,就是因为没有注意到这个问题,所以在传递中文参数时,有时候传递的参数正确,有时候参数在服务器端解码时就会出错。后来费了好大劲才发现是这个问题。

代码:

/**
 * base64编码工具类
 * @author wanggang
 * @version 2010-12-31
 */
public class Base64Util {

    /**
     *  将 s 进行 BASE64 编码
     * @param s
     * @return
     */
    public static String encode(byte[] s) {
        if (s == null)
            return null;
        return (new sun.misc.BASE64Encoder()).encode(s);
    }

    /**
     *  将 s 进行 BASE64 编码,针对url的编码
     * @param s
     * @return
     */
    public static String encodeForUrl(byte[] s){
        if (s == null)
            return null;
        String standerBase64 = encode(s);        
        String encodeForUrl = standerBase64;
        //转成针对url的base64编码
        encodeForUrl = encodeForUrl.replace("=", "");
        encodeForUrl = encodeForUrl.replace("+", "*");
        encodeForUrl = encodeForUrl.replace("/", "-");
        //去除换行
        encodeForUrl = encodeForUrl.replace("\n", "");
        encodeForUrl = encodeForUrl.replace("\r", "");
        
        //转换*号为 -x-
        //防止有违反协议的字符
        encodeForUrl = encodeSpecialLetter1(encodeForUrl);
       
        return encodeForUrl;
        
    }
    
    /**
     * 转换*号为 -x-,
                 为了防止有违反协议的字符,-x 转换为-xx
     * @param str
     * @return
     */
    private static String encodeSpecialLetter1(String str){
     str = str.replace("-x", "-xx");
     str = str.replace("*", "-x-");
     return str;
    }
    
    /**
     * 转换 -x-号为*,-xx转换为-x
     * @param str
     * @return
     */
    private static String decodeSpecialLetter1(String str){
     str = str.replace("-x-", "*");
  str = str.replace("-xx", "-x");
     return str;
    }
    /**
     *  将 s 进行 BASE64 编码
     * @param s
     * @return
     */
    public static String encode(String s) {
        
        if (s == null)
            return null;
        return encode(s.getBytes());
    }

    /**将 BASE64 编码的字符串 s 进行解码
     * 
     * @param s
     * @return
     */
    public static byte[] decode(String s) {
        if (s == null)
            return null;
        sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
        try {
            byte[] b = decoder.decodeBuffer(s);
            return b;
        } catch (Exception e) {
            return null;
        }
    }
    /**将 BASE64 编码的字符串 s 进行解码
     * 
     * @param s
     * @return
     */
    public static byte[] decodeForUrl(String s) {
        if (s == null)
            return null;
        s = decodeSpecialLetter1(s);
        s = s.replace("*", "+");
        s = s.replace("-", "/");
        s += "=";
        sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
        try {
            byte[] b = decoder.decodeBuffer(s );
            return b;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        String a = "将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码userId=1441&mailId=981&date=2011-02-15-62";
        String b = encodeForUrl(a.getBytes());
//        b = b.replace("\n", "");
//        b = b.replace("\r", "");
        System.out.println(b);
        
        
        System.out.println(new String(decodeForUrl(b)));
        
        b = encode(a.getBytes());
        System.out.println(b);
        System.out.println(new String(decode(b)));

    }

}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
java乱码总结
微信支付:body不是utf8编码
URLEncoder.encode 和 URLDecoder.decode 处理url的特殊参数
Base64
HTTP/2 服务端推送
Python 字符编码转换要诀
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服