java使用redis时,中文乱码问题

时间:2023-01-05 18:47:24

今天测试项目时发现页面有些数据乱码了,检查了一下发现数据存入redis还是中文,取出来就乱码了T T

代码:

 /** 存入相应的key和value,并设置其生命周期(单位秒) * @param key * @param value * @param liveTime * @throws Exception */
    public void set(String key, String value, long liveTime) throws Exception {
        this.set(key.getBytes(), value.getBytes(), liveTime);
    }
 /** 根据key取出对应的数据 * @param key * @return */
    public String get(final String key) {
        return redisTemplate.execute(new RedisCallback<String>() {
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                try {
                    byte[] b = connection.get(key.getBytes());
                    if(b==null){
                        return null;
                    }
                    return new String(b, "utf-8");

                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                return "";
            }
        });
    }

这里查了一下String的getBytes()方法的源码,如果你不设置编码集,默认的编码集是 “ISO-8859-1”,源码:

 /** * Encodes this {@code String} into a sequence of bytes using the * platform's default charset, storing the result into a new byte array. * * <p> The behavior of this method when this string cannot be encoded in * the default charset is unspecified. The {@link * java.nio.charset.CharsetEncoder} class should be used when more control * over the encoding process is required. * * @return The resultant byte array * * @since JDK1.1 */
public byte[] getBytes() {
        return StringCoding.encode(value, 0, value.length);
    }

static byte[] encode(char[] ca, int off, int len) {
        String csn = Charset.defaultCharset().name();
        try {
            // use charset name encode() variant which provides caching.
            return encode(csn, ca, off, len);
        } catch (UnsupportedEncodingException x) {
            warnUnsupportedCharset(csn);
        }
        try {
            return encode("ISO-8859-1", ca, off, len);
        } catch (UnsupportedEncodingException x) {
            // If this code is hit during VM initialization, MessageUtils is
            // the only way we will be able to get any kind of error message.
            MessageUtils.err("ISO-8859-1 charset not available: "
                             + x.toString());
            // If we can not find ISO-8859-1 (a required encoding) then things
            // are seriously wrong with the installation.
            System.exit(1);
            return null;
        }
    }

static byte[] encode(String charsetName, char[] ca, int off, int len)
        throws UnsupportedEncodingException
    {
        StringEncoder se = deref(encoder);
        String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
        if ((se == null) || !(csn.equals(se.requestedCharsetName())
                              || csn.equals(se.charsetName()))) {
            se = null;
            try {
                Charset cs = lookupCharset(csn);
                if (cs != null)
                    se = new StringEncoder(cs, csn);
            } catch (IllegalCharsetNameException x) {}
            if (se == null)
                throw new UnsupportedEncodingException (csn);
            set(encoder, se);
        }
        return se.encode(ca, off, len);
    }

我们只需要在设置key对应的value时设置对应的字符集与取出来的一直即可,在此我们设置为 “utf-8”,代码如下:

/** * @param key * @param value * @param liveTime * @throws Exception */
    public void set(String key, String value, long liveTime) throws Exception {
        this.set(key.getBytes("utf-8"), value.getBytes("utf-8"), liveTime);
    }

查阅资料时,发现直接操作redis也会有乱码的情况,记录一下

redis> set test "我们"  
OK  
redis> get test  
"\xe6\x88\x91\xe4\xbb\xac"  

如何在get时取到它的中文呢?只需要在redis-cli 后面加上 –raw

redis> get test  
"我们"  

感谢 http://blog.csdn.net/cwallow/article/details/8690309