
源码地址:/lcxm-common - JavaTimeSerializerFactory
20250825
Hessian 4.0.65 默认不支持 JDK 8 时间类型 (LocalDate
、LocalDateTime
、LocalTime
) 的序列化/反序列化。原始实现使用单独的 SerializerFactory
,重复代码多,不支持泛型对象,也不方便扩展其他时间类型。
JavaTimeSerializerFactory
统一工厂 JavaTimeSerializerFactory
,特性:
LocalDate
、LocalDateTime
、LocalTime
、OffsetDateTime
、ZonedDateTime
、YearMonth
Serializer
和 Deserializer
,提高性能JavaTimeHandler
<T>封装时间类型的解析和格式化逻辑:
public class JavaTimeHandler<T> {
final Class<T> type;
final DateTimeFormatter formatter;
final Function<String, T> parser;
final Function<T, String> formatterFunc;
public JavaTimeHandler(Class<T> type,
DateTimeFormatter formatter,
Function<String, T> parser,
Function<T, String> formatterFunc) { ... }
public String format(Object obj) { return formatterFunc.apply(type.cast(obj)); }
public T parse(String str) { return parser.apply(str); }
}
JavaTimeSerializer
<T>序列化为 Hessian Map 结构:
public class JavaTimeSerializer<T> extends AbstractSerializer {
private static final String KEY = "_value";
private final JavaTimeHandler<T> handler;
public JavaTimeSerializer(JavaTimeHandler<T> handler) { this.handler = handler; }
@Override
public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
String dateStr = handler.format(obj);
out.writeMapBegin(handler.type.getName());
out.writeString(KEY);
out.writeString(dateStr);
out.writeMapEnd();
}
}
JavaTimeDeserializer
<T>反序列化 Hessian Map 为时间对象:
public class JavaTimeDeserializer<T> extends AbstractDeserializer {
private static final String KEY = "_value";
private final JavaTimeHandler<T> handler;
public JavaTimeDeserializer(JavaTimeHandler<T> handler) { this.handler = handler; }
@Override
public Object readMap(AbstractHessianInput in) throws IOException {
String dateStr = null;
while (!in.isEnd()) {
String key = in.readString();
if (KEY.equals(key)) {
dateStr = in.readString();
} else {
in.readObject();
}
}
in.readMapEnd();
return dateStr == null ? null : handler.parse(dateStr);
}
@Override
public Class<?> getType() { return handler.type; }
}
JavaTimeSerializerFactory
统一管理 JDK8 时间类型的 Hessian 序列化逻辑:
public class JavaTimeSerializerFactory extends AbstractSerializerFactory {
private static final JavaTimeSerializerFactory instance = new JavaTimeSerializerFactory();
public static JavaTimeSerializerFactory getInstance() { return instance; }
private final Map<Class<?>, JavaTimeHandler<?>> handlers = new HashMap<>();
private final Map<Class<?>, Serializer> serializerCache = new HashMap<>();
private final Map<Class<?>, Deserializer> deserializerCache = new HashMap<>();
private JavaTimeSerializerFactory() { registerDefaults(); }
private void registerDefaults() {
// LocalDate
register(LocalDate.class, DateTimeFormatter.ISO_LOCAL_DATE,
str -> LocalDate.parse(str, DateTimeFormatter.ISO_LOCAL_DATE),
date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE));
// LocalDateTime
register(LocalDateTime.class, DateTimeFormatter.ISO_LOCAL_DATE_TIME,
str -> LocalDateTime.parse(str, DateTimeFormatter.ISO_LOCAL_DATE_TIME),
dt -> dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
// LocalTime
register(LocalTime.class, DateTimeFormatter.ISO_LOCAL_TIME,
str -> LocalTime.parse(str, DateTimeFormatter.ISO_LOCAL_TIME),
t -> t.format(DateTimeFormatter.ISO_LOCAL_TIME));
// OffsetDateTime
register(OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,
str -> OffsetDateTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME),
dt -> dt.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
// ZonedDateTime
register(ZonedDateTime.class, DateTimeFormatter.ISO_ZONED_DATE_TIME,
str -> ZonedDateTime.parse(str, DateTimeFormatter.ISO_ZONED_DATE_TIME),
dt -> dt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
// YearMonth
register(YearMonth.class, DateTimeFormatter.ofPattern("yyyy-MM"),
str -> YearMonth.parse(str, DateTimeFormatter.ofPattern("yyyy-MM")),
ym -> ym.format(DateTimeFormatter.ofPattern("yyyy-MM")));
}
public <T> void register(Class<T> clazz,
DateTimeFormatter formatter,
Function<String, T> parser,
Function<T, String> formatterFunc) {
handlers.put(clazz, new JavaTimeHandler<>(clazz, formatter, parser, formatterFunc));
}
@Override
public Serializer getSerializer(Class cl) {
return serializerCache.computeIfAbsent(cl, c -> {
JavaTimeHandler<?> handler = handlers.get(c);
return handler != null ? new JavaTimeSerializer<>(handler) : null;
});
}
@Override
public Deserializer getDeserializer(Class cl) {
return deserializerCache.computeIfAbsent(cl, c -> {
JavaTimeHandler<?> handler = handlers.get(c);
return handler != null ? new JavaTimeDeserializer<>(handler) : null;
});
}
}
封装 Hessian 序列化/反序列化逻辑:
public class Hessian2Serializer implements XqdSerializer {
public static final SerializerFactory serializerFactory = SerializerFactory.createDefault();
static {
serializerFactory.addFactory(JavaTimeSerializerFactory.getInstance());
}
@Override
public <T> byte[] serialize(T obj) {
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
Hessian2Output out = new Hessian2Output(os);
out.setSerializerFactory(serializerFactory);
out.writeObject(obj);
out.flush();
return os.toByteArray();
} catch (Exception e) {
throw new CommonException("Hessian2 序列化失败", e);
}
}
@Override
public <T> T deserialize(byte[] data, Class<T> clazz) {
try (ByteArrayInputStream is = new ByteArrayInputStream(data)) {
Hessian2Input in = new Hessian2Input(is);
in.setSerializerFactory(serializerFactory);
return (T) in.readObject(clazz);
} catch (Exception e) {
throw new CommonException("Hessian2 反序列化失败", e);
}
}
@Override
public boolean selfDescribed() { return true; }
}
LocalDate date = LocalDate.now();
byte[] bytes = serializer.serialize(date);
LocalDate result = serializer.deserialize(bytes, LocalDate.class);
System.out.println(result);
TestModel model = new TestModel();
model.setDate(LocalDate.now());
byte[] bytes = serializer.serialize(model);
TestModel result = serializer.deserialize(bytes, TestModel.class);
System.out.println(result.getDate());
XqdResponse<LocalDate> resp = XqdResponse.success(LocalDate.now());
byte[] bytes = serializer.serialize(resp);
XqdResponse result = serializer.deserialize(bytes, XqdResponse.class);
System.out.println(result.getData());
序列化流程:
反序列化流程:
LocalDate
、LocalDateTime
、LocalTime
、OffsetDateTime
、ZonedDateTime
、YearMonth
LocalDateSerializerFactory
和 LocalDateTimeSerializerFactory
JavaTimeSerializerFactory.register()
扩展新类型