相同的代码在main中和servlet中结果不同 Charset.defaultCharset

在进行加解密的时候,同样的代码,在main中可以正常解密,在servlet中却是乱码。。。

可以排除代码和加密算法问题,应该是编码有问题

String de = EncryptUtil.decryptAes("5lbDEpBwfXhKWqvrMFyD6A==", "3gsuK6rfsWT9rTUd");
//上面这句在servlet中执行结果为乱码

最后发现问题:太粗心了,在返回解密后的字符串时没有指定编码格式,结果Charset.defaultCharset().name()==GBK,就乱了

public static String decryptAes(String data,String key) throws Exception{
        Key k = toKey(key);
        Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding");
        IvParameterSpec iv = new IvParameterSpec(key.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, k,iv);
        return new String(cipher.doFinal(decryptBASE64(data)),"utf-8");//默认GBK,应指定utf-8
}

当程序在需要指定编码的地方没有显示指定编码格式,那么他会实用Charset.defaultCharset().name()作为默认编码格式。

而这个编码格式可以自行设置myeclipsexia:window-->preferences-->Installed JRES-->jkd_1.7.0_21-->Default VM Arguments-->-Dfile.encoding=UTF-8,如果没有进行设置,那么这个默认编码会通过底层操作系统来进行设置,个人感觉应该是根据系统的时区和地区

查看源码如下:

/**
     * Returns the default charset of this Java virtual machine.
     *
     * <p> The default charset is determined during virtual-machine startup and
     * typically depends upon the locale and charset of the underlying
     * operating system.
     *
     * @return  A charset object for the default charset
     *
     * @since 1.5
     */
    public static Charset defaultCharset() {
        if (defaultCharset == null) {
            synchronized (Charset.class) {
                String csn = AccessController.doPrivileged(
                    new GetPropertyAction("file.encoding"));
                Charset cs = lookup(csn);
                if (cs != null)
                    defaultCharset = cs;
                else
                    defaultCharset = forName("UTF-8");
            }
        }
        return defaultCharset;
    }

  
private static Charset lookup(String charsetName) {
    if (charsetName == null)
    throw new IllegalArgumentException("Null charset name");

    Object[] a;
    if ((a = cache1) != null && charsetName.equals(a[0]))
    return (Charset)a[1];
    // We expect most programs to use one Charset repeatedly.
    // We convey a hint to this effect to the VM by putting the
    // level 1 cache miss code in a separate method.
    return lookup2(charsetName);
}

这个cache不晓得是干啥的,还有,main和servlet中这defaultCharset有时会不通?

 

posted @ 2016-06-28 16:18  暗夜心慌方  阅读(790)  评论(1编辑  收藏  举报