在使用Protostuff进行序列化的时候,Timestamp作为字段,通过Protostuff转换后的结果都是1970-01-01 08:00:00的问题。
ProtostuffSerializer为序列化代码,实现Codec接口,在原有序列化代码上增加了如下几行:
private final static Delegate<Timestamp> TIMESTAMP_DELEGATE = new TimestampDelegate();
private final static DefaultIdStrategy idStrategy = ((DefaultIdStrategy) RuntimeEnv.ID_STRATEGY);
static {
idStrategy.registerDelegate(TIMESTAMP_DELEGATE);
}
package com.actionsoft.apps.wide.redis.serializable;
import java.sql.Timestamp;
import java.util.concurrent.ConcurrentHashMap;
import com.actionsoft.apps.wide.redis.utils.Codec;
import com.actionsoft.apps.wide.redis.utils.TimestampDelegate;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.DefaultIdStrategy;
import com.dyuproject.protostuff.runtime.Delegate;
import com.dyuproject.protostuff.runtime.RuntimeEnv;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
/**
* protostuff对象序列化工具 J2SE 1.8
* @version 1.0
*/
public class ProtostuffSerializer implements Codec{
private static ConcurrentHashMap<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>();
private final static Delegate<Timestamp> TIMESTAMP_DELEGATE = new TimestampDelegate();
private final static DefaultIdStrategy idStrategy = ((DefaultIdStrategy) RuntimeEnv.ID_STRATEGY);
static {
idStrategy.registerDelegate(TIMESTAMP_DELEGATE);
}
@Override
public short getId() {
return 0;
}
@Override
public <T> byte[] serialize(final T source) {
VO<T> vo = new VO<T>(source);
final LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
try {
final Schema<VO> schema = getSchema(VO.class);
return serializeInternal(vo, schema, buffer);
} catch (final Exception e) {
throw new IllegalStateException(e.getMessage(), e);
} finally {
buffer.clear();
}
}
@Override
public <T> T deserialize(final byte[] bytes) {
try {
Schema<VO> schema = getSchema(VO.class);
VO vo = deserializeInternal(bytes, schema.newMessage(), schema);
if (vo != null && vo.getValue() != null) {
return (T) vo.getValue();
}
} catch (final Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
return null;
}
private <T> byte[] serializeInternal(final T source, final Schema<T> schema, final LinkedBuffer buffer) {
return ProtostuffIOUtil.toByteArray(source, schema, buffer);
}
private <T> T deserializeInternal(final byte[] bytes, final T result, final Schema<T> schema) {
ProtostuffIOUtil.mergeFrom(bytes, result, schema);
return result;
}
private static <T> Schema<T> getSchema(Class<T> clazz) {
@SuppressWarnings("unchecked")
Schema<T> schema = (Schema<T>) cachedSchema.get(clazz);
if (schema == null) {
schema = RuntimeSchema.createFrom(clazz);
cachedSchema.put(clazz, schema);
}
return schema;
}
}
package com.actionsoft.apps.wide.redis.utils;
public interface Codec {
/**
* 编解码器ID,用于标识编解码器
* @return
*/
public short getId();
/**
* 把对象数据结构编码成一个DataBuffer
* @param <T>
*/
public <T> byte[] serialize(T obj);
/**
* 把DataBuffer解包构造一个对象
* @param <T>
*/
public <T> T deserialize(byte[] bytes);
}
package com.actionsoft.apps.wide.redis.utils;
import java.io.IOException;
import java.sql.Timestamp;
import com.dyuproject.protostuff.Input;
import com.dyuproject.protostuff.Output;
import com.dyuproject.protostuff.Pipe;
import com.dyuproject.protostuff.WireFormat.FieldType;
import com.dyuproject.protostuff.runtime.Delegate;
public class TimestampDelegate implements Delegate<Timestamp> {
public FieldType getFieldType() {
return FieldType.FIXED64;
}
public Class<?> typeClass() {
return Timestamp.class;
}
public Timestamp readFrom(Input input) throws IOException {
return new Timestamp(input.readFixed64());
}
public void writeTo(Output output, int number, Timestamp value,
boolean repeated) throws IOException {
output.writeFixed64(number, value.getTime(), repeated);
}
@Override
public void transfer(Pipe pipe, Input input, Output output, int number,
boolean repeated) throws IOException {
output.writeFixed64(number, input.readFixed64(), repeated);
}
}
注:其他序列化及Redis代码,详见前两篇