Spring Batch - 如何将String从文件转换为Date?

时间:2012-01-30 04:51:27

标签: java spring spring-batch

我正在尝试处理一个CSV文件,其中某些字段是格式为"yyyy-MM-dd"的日期 - 但读者在尝试将CS​​V文件中的字符串转换为模型类中的日期时失败

错误是:

  

org.springframework.validation.BindException:   org.springframework.validation.BeanPropertyBindingResult:1错误   字段'datetimeInactive'上对象'target'中的字段错误:被拒绝   价值[2011-04-27];代码   [typeMismatch.target.datetimeInactive,typeMismatch.datetimeInactive,typeMismatch.java.util.Date,typeMismatch];   参数   [org.springframework.context.support.DefaultMessageSourceResolvable:   代码[target.datetimeInactive,datetimeInactive];参数[];   默认消息[datetimeInactive]];默认消息[失败   将'java.lang.String'类型的属性值转换为所需类型   属性'datetimeInactive'的'java.util.Date';嵌套异常是   java.lang.IllegalStateException:无法转换类型的值   [java.lang.String]为属性所需的类型[java.util.Date]   'datetimeInactive':找不到匹配的编辑器或转换策略]

读者的XML:

http://code.google.com/p/springbatch-in-action/source/browse/trunk/sbia/ch07/src/test/resources/com/manning/sbia/ch07/test-batch-reader-context.xml?r=145

在我的XML配置文件中,我有以下bean:

  <bean id="dateEditor" class="org.springframework.beans.propertyeditors.CustomDateEditor">
    <constructor-arg>
      <bean class="java.text.SimpleDateFormat">
        <constructor-arg value="yyyy-MM-dd" />
      </bean>
    </constructor-arg>
    <constructor-arg value="true" />
  </bean>

  <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
      <map>
        <entry key="java.util.Date">
          <ref local="dateEditor" />
        </entry>
      </map>
    </property>
  </bean>

我的问题是:

  1. 我在上下文中定义了一个CustomDateEditor - 为什么Spring不能将String转换为Date?

  2. 我已经读过在Spring 3中有一种更新的方法(Converter?)来完成转换。即http://forum.springsource.org/showthread.php?108480-Register-TypeConverter-PropertyEditor-w-Spring-Batch - 但是,我在Spring Batch文档中找不到任何示例代码。你能否在这里展示如何做到这一点/指出我的一些链接?

  3. 更新

    我得到了问题#2的答案:

    XML:

      <mvc:annotation-driven conversion-service="conversionService" />
    
      <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="my.project.StringToDate">
                    <!-- org.springframework.binding.convert.converters.StringToDate DEFAULT_PATTERN = "yyyy-MM-dd" -->
                    <property name="pattern" value="yyyy-MM-dd" />
                </bean>
            </set>
        </property>
      </bean>
    

    自定义转换器:

    package my.project;
    
    import java.util.Date;
    
    import org.springframework.core.convert.converter.Converter;
    
    public class StringToDate extends org.springframework.binding.convert.converters.StringToDate implements Converter<String, Date> {
    
        public Date convert(String source) {
    
            Date date = null;
    
            try {
                date = (Date) convertSourceToTargetClass(getPattern(), getTargetClass());
            } catch (Exception e) {
    
            }
    
            return date;
        }
    
    }
    

    我仍在寻找问题#1的答案。即,在设置转换器之后,我仍然在批处理任务期间获得BindException。从this forum thread开始,看起来我的代码应该执行转换。

    堆栈跟踪是:

    Caused by: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
    Field error in object 'target' on field 'datetimeInactive': rejected value [2011-04-27]; codes [typeMismatch.target.datetimeInactive,typeMismatch.datetimeInactive,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.datetimeInactive,datetimeInactive]; arguments []; default message [datetimeInactive]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'datetimeInactive'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'datetimeInactive': no matching editors or conversion strategy found]
    Field error in object 'target' on field 'datetimeActive': rejected value [2011-04-27]; codes [typeMismatch.target.datetimeActive,typeMismatch.datetimeActive,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.datetimeActive,datetimeActive]; arguments []; default message [datetimeActive]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'datetimeActive'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'datetimeActive': no matching editors or conversion strategy found]
        at org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper.mapFieldSet(BeanWrapperFieldSetMapper.java:186)
        at org.springframework.batch.item.file.mapping.DefaultLineMapper.mapLine(DefaultLineMapper.java:42)
        at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:179)
        ... 45 more
    

1 个答案:

答案 0 :(得分:3)

您的论坛参考用于构建应用程序上下文和配置bean时的类型转换

查看BeanWrapperFieldSetMapper

的JavaDoc
  

自定义FieldSet值转换为所需的方式   注入原型的类型有几种选择。您   可以直接通过customEditors 注入PropertyEditor实例   * property *,或者你可以覆盖createBinder(Object)和   initBinder(DataBinder)方法,或者您可以提供自定义FieldSet   实施

意味着您应该将CustomDateEditor直接注入Mapper