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;
}
}