源码地址:/lcxm-common - JavaTimeSerializerFactory
20250825
Hessian 4.0.65 默认不支持 JDK 8 时间类型 (LocalDate、LocalDateTime、LocalTime) 的序列化/反序列化。原始实现使用单独的 SerializerFactory,重复代码多,不支持泛型对象,也不方便扩展其他时间类型。
JavaTimeSerializerFactory统一工厂 JavaTimeSerializerFactory,特性:
LocalDate、LocalDateTime、LocalTime、OffsetDateTime、ZonedDateTime、YearMonthSerializer 和 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; }@Overridepublic 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; }@Overridepublic 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);}@Overridepublic 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() {// LocalDateregister(LocalDate.class, DateTimeFormatter.ISO_LOCAL_DATE,str -> LocalDate.parse(str, DateTimeFormatter.ISO_LOCAL_DATE),date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE));// LocalDateTimeregister(LocalDateTime.class, DateTimeFormatter.ISO_LOCAL_DATE_TIME,str -> LocalDateTime.parse(str, DateTimeFormatter.ISO_LOCAL_DATE_TIME),dt -> dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));// LocalTimeregister(LocalTime.class, DateTimeFormatter.ISO_LOCAL_TIME,str -> LocalTime.parse(str, DateTimeFormatter.ISO_LOCAL_TIME),t -> t.format(DateTimeFormatter.ISO_LOCAL_TIME));// OffsetDateTimeregister(OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,str -> OffsetDateTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME),dt -> dt.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));// ZonedDateTimeregister(ZonedDateTime.class, DateTimeFormatter.ISO_ZONED_DATE_TIME,str -> ZonedDateTime.parse(str, DateTimeFormatter.ISO_ZONED_DATE_TIME),dt -> dt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));// YearMonthregister(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));}@Overridepublic Serializer getSerializer(Class cl) {return serializerCache.computeIfAbsent(cl, c -> {JavaTimeHandler<?> handler = handlers.get(c);return handler != null ? new JavaTimeSerializer<>(handler) : null;});}@Overridepublic 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());}@Overridepublic <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);}}@Overridepublic <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);}}@Overridepublic 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、YearMonthLocalDateSerializerFactory 和 LocalDateTimeSerializerFactoryJavaTimeSerializerFactory.register() 扩展新类型