Skip to content

Java 反序列化在 C# 中保存到 Redis 的数据

因为两个项目共用的 Redis 缓存,获取在 C# 中保存的数据时反序列化出错。C# 中保存的获取的数据取出来后如下:

js
{"Guid":"ee7a6e30cf98497b9906e25790b03485","Serial":300,"CreateDate":"\/Date(1423292741000-0000)\/","IsOpen":false}

Guid 中没有中间的横线 -,日期类型的格式也比较奇怪。于是使用 Jackson 的自定义序列化及反序列化,使 Java 和 C# 保存到 Redis 中的数据保持一致。

Guid 的反序列化类 (GuidDeserializer)

java
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;

import java.io.IOException;

/**
 * Created by liujiajia on 2017/2/20.
 */
public class GuidDeserializer extends JsonDeserializer {
    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        byte[] newGuid = new byte[36];
        byte[] oldGuid = jsonParser.getText().getBytes();

        int j = 0;
        for (int i = 0; i < newGuid.length; i++) {
            if (i == 8 || i == 13 || i == 18 || i == 23) {
                newGuid[i] = '-';
            } else {
                newGuid[i] = oldGuid[j];
                j++;
            }
        }

        return new String(newGuid);
    }
}

日期类型的反序列化类 (DateDeserializer)

java
import org.apache.commons.httpclient.util.DateUtil;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by liujiajia on 2017/2/20.
 */
public class DateDeserializer extends JsonDeserializer {
    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        String strDate = jsonParser.getText();
        Pattern p = Pattern.compile("\\/Date\\((\\d{13})-(\\d{4})\\)\\/");
        Matcher m = p.matcher(strDate);
        while (m.find()) {
            Date date = new Date(Long.parseLong(m.group(1)));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            return sdf.format(date);
        }

        return strDate;
    }
}

Guid 序列化的类 (GuidNoBarSerializer)

java
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;

import java.io.IOException;

/**
 * Created by liujiajia on 2017/2/20.
 */
public class GuidNoBarSerializer extends JsonSerializer {
    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        jsonGenerator.writeString(s.toLowerCase().replace("-", ""));
    }
}

日期类型的序列化类 (DateSerializer)

java
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;

/**
 * Created by liujiajia on 2017/2/20.
 */
public class DateSerializer extends JsonSerializer {
    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        try {
            Date date = DateFormat.getDateTimeInstance().parse(s);
            jsonGenerator.writeString("/Date(" + String.valueOf(date.getTime()) + "-0000)/");
        } catch (ParseException e) {
            jsonGenerator.writeString(s);
        }
    }
}

模型中使用上面的自定义标注 (因为 java 中的字段一般是小写开头的, 所以还要加上 JsonProperty 标注, 使字段名和 C# 中的属性名匹配):

java
/**
 * ID
 */
@JsonProperty("Guid")
@JsonSerialize(using = GuidNoBarSerializer.class)
@JsonDeserialize(using = GuidDeserializer.class)
private String guid;

/**
 * 创建时间
 */
@JsonProperty("CreateDate")
@JsonSerialize(using = DateSerializer.class)
@JsonDeserialize(using = DateDeserializer.class)
private String createDate;

从 Redis 中获取时的代码:

java
public static boolean setJsonObjectKey(String key, Object value) {
    try (Jedis jedis = getRedisUtils().getMasterJedisPool().getResource())
    {
        jedis.set(key, new ObjectMapper().writeValueAsString(value));
        jedis.expire(key.getBytes(), _default_expire_secondes);
        return true;
    } catch (Exception ex) {
        return false;
    }
}

public static  T getJsonObjectValue(String key, Class clazz) {
    try (Jedis jedis = getRedisUtils().getSlaveJedisPool().getResource())
    {
        String json = jedis.get(key);
        return new ObjectMapper().readValue(json, clazz);
    } catch (Exception ex) {
        return null;
    }
}

public static  T getJsonObjectValue(String key, TypeReference valueTypeRef) {
    try (Jedis jedis = getRedisUtils().getSlaveJedisPool().getResource())
    {
        String json = jedis.get(key);
        return new ObjectMapper().readValue(json, valueTypeRef);
    } catch (Exception ex) {
        return null;
    }
}

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.