java base64 空格_通过 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)));

}

}

你可能感兴趣的:(java,base64,空格)