Spring Batch:读取日期字符串并转换为指定格式的问题
解决方案
你的核心问题是当前自定义的PropertyEditor针对LocalDate类型,但模型类中的日期字段是String类型,因此编辑器不会生效。要实现将源日期格式字符串转换为yyyyMMdd格式字符串的需求,可通过以下两种方式调整代码:
方式一:重写mapFieldSet直接处理特定字段
这种方式更直观,仅对目标日期字段做格式转换,不影响其他String字段:
public class MyBeanWrapperFieldSetMapper<T> extends BeanWrapperFieldSetMapper<T> { // 源日期格式:匹配月份后两个空格、带毫秒和AM/PM的格式 DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm:ss:SSSa", Locale.US); // 目标日期格式 DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern("yyyyMMdd"); @Override public T mapFieldSet(FieldSet fieldSet) throws BindException { // 先完成默认字段映射 T bean = super.mapFieldSet(fieldSet); BeanWrapper beanWrapper = new BeanWrapperImpl(bean); // 处理createdDt字段 String createdDtRaw = fieldSet.readString("createdDt"); if (StringUtils.isNotEmpty(createdDtRaw)) { try { LocalDateTime dateTime = LocalDateTime.parse(createdDtRaw, sourceFormatter); beanWrapper.setPropertyValue("createdDt", dateTime.format(targetFormatter)); } catch (DateTimeParseException e) { // 解析失败时的处理,可根据业务调整 beanWrapper.setPropertyValue("createdDt", ""); } } // 处理repliedDt字段 String repliedDtRaw = fieldSet.readString("repliedDt"); if (StringUtils.isNotEmpty(repliedDtRaw)) { try { LocalDateTime dateTime = LocalDateTime.parse(repliedDtRaw, sourceFormatter); beanWrapper.setPropertyValue("repliedDt", dateTime.format(targetFormatter)); } catch (DateTimeParseException e) { beanWrapper.setPropertyValue("repliedDt", ""); } } return bean; } }
方式二:为特定String字段注册自定义PropertyEditor
通过PropertyEditor机制,仅对createdDt和repliedDt字段应用格式转换:
public class MyBeanWrapperFieldSetMapper<T> extends BeanWrapperFieldSetMapper<T> { DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm:ss:SSSa", Locale.US); DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern("yyyyMMdd"); @Override protected void initBinder(DataBinder binder) { super.initBinder(binder); // 为createdDt字段注册编辑器 binder.registerCustomEditor(String.class, "createdDt", new PropertyEditorSupport() { @Override public void setAsText(String text) throws IllegalArgumentException { if (StringUtils.isNotEmpty(text)) { try { LocalDateTime dateTime = LocalDateTime.parse(text, sourceFormatter); setValue(dateTime.format(targetFormatter)); } catch (DateTimeParseException e) { setValue(""); } } else { setValue(""); } } }); // 为repliedDt字段注册编辑器 binder.registerCustomEditor(String.class, "repliedDt", new PropertyEditorSupport() { @Override public void setAsText(String text) throws IllegalArgumentException { if (StringUtils.isNotEmpty(text)) { try { LocalDateTime dateTime = LocalDateTime.parse(text, sourceFormatter); setValue(dateTime.format(targetFormatter)); } catch (DateTimeParseException e) { setValue(""); } } else { setValue(""); } } }); } }
关键注意事项
- 源格式匹配:确保
MMM d中的两个空格与源文件日期格式完全一致(比如Apr 1是两个空格),否则会解析失败。 - 异常处理:可根据业务需求调整解析失败的逻辑,比如保留原始值、抛出异常或设为空。
- 依赖检查:确保引入
org.springframework.beans.BeanWrapper、BeanWrapperImpl以及Java 8+时间API相关类。
内容的提问来源于stack exchange,提问作者PAA
相关产品推荐
相关产品推荐

