ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Apache Fesod 自定义转换器(Custom Converter)实战:读写双向转换、字段级与全局注册及底层解析原理

Apache Fesod 自定义转换器(Custom Converter)实战:读写双向转换、字段级与全局注册及底层解析原理 后端【免费下载链接】fesodFast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.项目地址https://gitcode.com/gh_mirrors/fast/fesod点击查看免费下载导读本文聚焦 Apache FesodIncubating表格处理框架中的自定义数据转换器Converter机制讲解如何基于ConverterT接口编写读写双向的自定义转换逻辑并通过ExcelProperty(converter ...)字段级注册与 builder 级.registerConverter(...)全局注册两种方式接入框架同时结合仓库源码剖析转换器的键key构建、默认转换器装载与解析优先级。读完本文你将能够在 Fesod 中自由定制单元格与 Java 对象之间的数据映射例如给 String 加上前后缀、自定义时间戳格式化、特殊枚举转换等而无需修改框架内置逻辑。一、Converter 是什么读写双向的数据转换枢纽在 Apache Fesod 中Excel 单元格ReadCellData/WriteCellData与 Java 对象字段之间的双向转换统一由ConverterT接口承担读方向把 Excel 单元格数据转换为 Java 对象字段值convertToJavaData写方向把 Java 对象字段值转换为 Excel 单元格数据convertToExcelData。框架已为常见的 Java 类型String、Integer、Long、BigDecimal、Date、LocalDate、LocalDateTime、LocalTime、布尔、字节、短整型、浮点、图片、URL 等预置了大量内置转换器位于 fesod-sheet/src/main/java/org/apache/fesod/sheet/converters/ 目录下。当内置转换器无法满足业务需求例如需要对字符串做前后缀加工、读取原始单元格元数据、按特定规则解析自定义格式时即可编写自定义转换器并注册使用。官方指南 website/docs/sheet/advanced/custom-converter.md 完整阐述了这一机制自定义转换器既可逐字段注册通过注解也可全局注册通过 builder并且同时作用于读取与写入两个方向。二、创建自定义 Converter接口逐方法拆解2.1 实现一个最简单的自定义转换器以下代码取自官方指南的完整示例实现了一个给字符串加Custom: 前缀的转换器public class CustomStringStringConverter implements ConverterString { Override public Class? supportJavaTypeKey() { return String.class; } Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } Override public String convertToJavaData(ReadConverterContext? context) { return Custom: context.getReadCellData().getStringValue(); } Override public WriteCellData? convertToExcelData(WriteConverterContextString context) { return new WriteCellData(Custom: context.getValue()); } }2.2 接口方法的职责与签名查看接口源码 Converter.java 可以确认ConverterT共定义四个核心方法均带默认实现未覆盖时抛出UnsupportedOperationException方法方向作用supportJavaTypeKey()元信息声明该转换器支持的 Java 类型如String.class用于注册键匹配supportExcelTypeKey()元信息声明该转换器支持的 Excel 单元格类型CellDataTypeEnum 枚举如STRING、NUMBER、BOOLEAN、DATE等convertToJavaData(ReadConverterContext? context)读将单元格数据转换为 Java 对象convertToExcelData(WriteConverterContextT context)写将 Java 对象转换为单元格数据2.3 上下文对象能拿到什么读上下文 ReadConverterContext.java包含readCellDataExcel 单元格数据非空、contentProperty字段属性可为空和analysisContext分析上下文非空可获取当前读取的全局配置。写上下文 WriteConverterContext.java包含valueJava 数据非空、contentProperty可为空和writeContext写入上下文。接口还提供了基于(value/cellData, contentProperty, globalConfiguration)三参签名的默认方法上述基于上下文的便捷方法会在内部自动委托调用它们因此你只需要覆盖适合自己场景的那一组即可。注意空值参考 NullableObjectConverter.java 的注释说明实现convertToExcelData时传入的value可能是null例如某行某列没有值务必做好空值判断。该接口本身是ConverterT的空扩展用于在语义上标记允许空值的转换器。三、两种注册方式字段级 vs 全局官方指南用一张表格清晰对比了两种注册方式方式作用范围如何注册Per-field字段级仅作用于单个字段ExcelProperty(converter MyConverter.class)Global全局作用于所有Java 类型 Excel 类型匹配的字段builder 上调用.registerConverter(new MyConverter())3.1 字段级注册注解方式查看 ExcelProperty.java 源码注解提供converter()属性类型为Class? extends Converter?默认值为AutoConverter.class即按类型自动匹配见 AutoConverter.java它只是一个空实现标记实际转换由内置转换器完成public class DemoData { // 仅对 name 字段生效写入时自动加前缀读取时自动去自定义加工 ExcelProperty(value 姓名, converter CustomStringStringConverter.class) private String name; ExcelProperty(年龄) private Integer age; }这种方式适合个别字段有特殊格式、而同一类型其他字段保持默认行为的场景。3.2 全局注册builder 方式在读写 builder 上调用.registerConverter(converter)。该方法的底层实现在 AbstractParameterBuilder.java约 L122 起它会将传入的转换器追加到parameter().getCustomConverterList()自定义转换器列表中后续构建 holder 时再统一合并进转换器 Map。全局注册适合某一类型整体都需要自定义转换的场景例如项目中所有Timestamp字段都要按自定义格式输出。测试 CustomConverterTest.java 中的converterMapTest与globalConverterInSheetHolder验证了全局注册后转换器确实会以(Java 类型, Excel 类型)为键出现在 writer/sheet holder 的converterMap()中。四、全局注册的完整读写示例4.1 写入Write with Global Converter官方指南给出的写入示例Test public void customConverterWrite() { String fileName customConverterWrite System.currentTimeMillis() .xlsx; FesodSheet.write(fileName, DemoData.class) .registerConverter(new CustomStringStringConverter()) .sheet() .doWrite(data()); }4.2 读取Read with Global ConverterTest public void customConverterRead() { String fileName path/to/demo.xlsx; FesodSheet.read(fileName, DemoData.class, new DemoDataListener()) .registerConverter(new CustomStringStringConverter()) .sheet() .doRead(); }4.3 可组合注册多个转换器.registerConverter支持链式多次调用同一个转换器列表会依次收集。仓库测试中的writeCsv/writeXls/writeXlsx用例就同时注册了TimestampNumberConverter与TimestampStringConverter两个转换器见 CustomConverterTest.java L125-L131并分别输出 CSV、XLS、XLSX 三种格式说明该机制对 CSV/XLS/XLSX 均生效。五、转换器解析优先级Resolution Priority官方指南明确给出了三层优先级从高到低字段级转换器ExcelProperty(converter ...)——优先级最高builder 级转换器.registerConverter(...)——次之内置默认转换器——优先级最低也就是说字段级注解会强制该字段使用指定转换器ExcelProperty源码注释原文为 Force the current field to use this converter即使同一类型已在全局注册了其他转换器也只对未标注注解的字段生效。测试 CustomConverterTest.java 中的fieldLevelConverterTakesPrecedenceOverRegisteredConverter用例验证了这一行为同一条数据里标注了ExcelProperty(converter FieldLevelStringConverter.class)的字段输出为field:value而仅依赖全局RegisteredStringConverter的字段输出为registered:value最终 CSV 内容断言为field:value,registered:value证明字段级转换器确实覆盖了全局注册的同类型转换器。六、底层原理转换器键ConverterKey与默认装载6.1 键 Java 类型 Excel 单元格类型全局转换器之所以能自动匹配所有符合类型的字段关键在于每个转换器都以(支持类型, 单元格类型)二元组作为唯一键存入 Map。源码 ConverterKeyBuild.java 实现如下buildKey(clazz, cellDataTypeEnum)生成ConverterKey(clazz, cellDataTypeEnum)内部维护一张装箱映射表BOXING_MAP把int/byte/long/double/float/char/short/boolean等基本类型自动映射为对应的包装类Integer/Byte/Long/Double/Float/Character/Short/Boolean因此自定义转换器声明supportJavaTypeKey()返回包装类型即可同时覆盖基本类型字段。6.2 默认转换器的装载DefaultConverterLoader.java 在类加载时初始化三组 MapdefaultWriteConverter写方向默认转换器键仅为 Java 类型如BigDecimalNumberConverter、DateDateConverter、FileImageConverter、UrlImageConverter等另有一批必须转成字符串的场景转换器如DateStringConverter、LocalDateTimeStringConverter等键为 Java 类型 STRING单元格类型allConverter全部转换器读方向默认即使用它loadDefaultReadConverter()直接返回loadAllConverter()统一以(Java 类型, Excel 类型)为键注册包括每个类型对应的Boolean/Number/String三种转换器变体以及图片、URL 等专用转换器。你的自定义转换器通过 builder 注册后会与这些内置 Map 合并复制默认 Map 后 put 自定义项从而在解析字段时优先命中自定义键。七、内置转换器速览与自定义场景建议从 DefaultConverterLoader.java 的初始化代码可以整理出框架内置支持的转换器族均位于converters/下对应子包目标类型子包常见转换器Stringstring/StringStringConverter、StringNumberConverter、StringBooleanConverter、StringErrorConverter、StringImageConverter、StringBase64ImageConverter、StringPathnameImageConverter数值类型integer/ longconverter/ doubleconverter/ floatconverter/ byteconverter/ shortconverter/各类型的Number/Boolean/String三件套高精度bigdecimal/ biginteger/BigDecimalNumberConverter、BigIntegerStringConverter等日期时间date/ localdate/ localdatetime/ localtime/DateDateConverter、LocalDateTimeStringConverter等布尔booleanconverter/BooleanBooleanConverter等图片/文件/URLbytearray/ file/ inputstream/ url/FileImageConverter、InputStreamImageConverter、ByteArrayImageConverter、UrlImageConverter配合 CidrBlock.java 等策略类使用适合编写自定义转换器的典型场景字符串加工前后缀、脱敏、编码转换——如本文示例自定义日期/时间格式或按业务规则解析日期字符串配合 website/docs/sheet/read/converter.md 的转换器主题一起学习Timestamp等 SQL 类型字段的读写参考测试中的TimestampStringConverter/TimestampNumberConverter见 fesod-sheet/src/test/java/org/apache/fesod/sheet/converter/需要拿到原始单元格类型如ReadCellData做精细判断的场景测试模型 ConverterReadData.java 展示了直接在字段上声明ReadCellData?的用法。八、实践建议与注意事项覆盖方法按需只读或只写的场景可只实现对应方向的convertToJavaData/convertToExcelData但元信息方法supportJavaTypeKey()与supportExcelTypeKey()必须如实返回否则注册键无法匹配。基本类型字段supportJavaTypeKey()建议返回包装类如Integer.classConverterKeyBuild会自动处理基本类型的装箱映射。空值处理写方向实现中显式判断value null参考NullableObjectConverter的语义说明。优先级陷阱字段级注解是强制的会完全覆盖全局与内置转换器若某字段只想用默认行为就不要给它标converter。全局注册的副作用registerConverter影响整个 workbook/sheet 中所有匹配类型的字段注册前请确认不会误伤其他字段的默认格式。相关阅读官方自定义转换器指南本文主体来源website/docs/sheet/advanced/custom-converter.md读取方向转换器详解website/docs/sheet/read/converter.md写入方向转换器详解website/docs/sheet/write/converter.md转换器接口与实现源码converters/优先级与全局注册验证测试CustomConverterTest.java赞分享后端【免费下载链接】fesodFast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.项目地址https://gitcode.com/gh_mirrors/fast/fesod点击查看免费下载相关推荐Doctrine ORM 自定义映射类型Custom Mapping Types完全指南从类型创建、注册到字段值转换实战Doctrine ORM 自定义映射类型Custom Mapping Types完全指南从类型创建、注册到字段值转换实战 Doctrine ORM 允许开数据库ORM后端深入 Spring Converter 接口从类型转换原理到自定义转换器实战spring-reading 源码实践深入 Spring Converter 接口从类型转换原理到自定义转换器实战spring reading 源码实践 Spring 的类型转换体系是数据绑定示例工程文档Apache Fesod扩展开发终极指南如何编写自定义转换器和处理器Apache Fesod扩展开发终极指南如何编写自定义转换器和处理器 Apache Fesod是一个快速、简洁、解决大文件内存溢出的Java处理Excel工具后端上一篇Potpie ContextResourceManager 认证失败结果修正ADR-0010 与 RM-036 至 RM-039 契约变更全解下一篇基于 vLLM-Omni 统一全双工服务栈部署 PersonaPlex80ms 锁步语音对话实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表