【问题标题】:Custom LineMapper throwing exception in Spring Batch multiple files process自定义 LineMapper 在 Spring Batch 多文件过程中抛出异常
【发布时间】:2016-02-16 09:15:01
【问题描述】:

我正在尝试实现自定义线映射器,以下是我的代码。 当我运行此代码时,会引发异常(还添加了异常)
在我的资源文件中,每一行的分隔符可能不同。有些行的分隔符是 ',' 或 '|'我想在 CustomLineMapper 类中处理。

job-read-files.xml

<bean id="domain" class="com.di.pos.Domain" />
<job id="readMultiFileJob" xmlns="http://www.springframework.org/schema/batch">
    <step id="step1">
        <tasklet>
            <chunk reader="multiResourceReader" writer="flatFileItemWriter"
                commit-interval="1" />
            <!-- <listeners> <listener ref="customItemReaderListener" /> </listeners> -->
        </tasklet>
    </step>
</job>

<bean id="multiResourceReader" class="org.springframework.batch.item.file.MultiResourceItemReader">
    <property name="resources" value="file:csv/inputs/domain-*.csv" />
    <property name="delegate" ref="flatFileItemReader" />
</bean>

<bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="lineMapper">
    <!--    <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">-->
            <bean class="com.di.pos.CustomLineMapper">

            <property name="lineTokenizer">
                <bean
                    class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                    <property name="names" value="id, domain" />
                </bean>
            </property>
            <property name="fieldSetMapper">
                <bean
                    class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                    <property name="prototypeBeanName" value="domain" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

CustomLineMapper.java 这里我重写了一些方法。

public class CustomLineMapper<T> extends DefaultLineMapper<T> {
public LineTokenizer lineTokenizer;
public FieldSetMapper<Domain> fieldSetMapper;

@Override
public T mapLine(String line, int lineNumber) throws Exception {
    System.out.println("======" + line);

    DelimitedLineTokenizer delimitedLineTokenizer = new DelimitedLineTokenizer();

    if (line.indexOf("|") == -1) {
        if (line.indexOf(",") == -1) {
        } else {
            delimitedLineTokenizer.setDelimiter(",");
        }
    } else {
        delimitedLineTokenizer.setDelimiter("|");
    }
    setLineTokenizer(delimitedLineTokenizer);
    return (T) this.fieldSetMapper.mapFieldSet(this.lineTokenizer.tokenize(line));
}

public LineTokenizer getLineTokenizer() {
    return lineTokenizer;
}

public void setLineTokenizer(LineTokenizer lineTokenizer) {
    this.lineTokenizer = lineTokenizer;
}

public FieldSetMapper<Domain> getFieldSetMapper() {
    return fieldSetMapper;
}

@Override
public void setFieldSetMapper(FieldSetMapper<T> fieldSetMapper) {
    super.setFieldSetMapper(fieldSetMapper);
}

}

当我执行这段代码时,我得到了以下异常。

    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'step1': Cannot resolve reference to bean 'multiResourceReader' while setting bean property 'itemReader'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'multiResourceReader' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Cannot resolve reference to bean 'flatFileItemReader' while setting bean property 'delegate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flatFileItemReader' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Cannot create inner bean 'com.di.pos.CustomLineMapper#3c50507' of type [com.di.pos.CustomLineMapper] while setting bean property 'lineMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.di.pos.CustomLineMapper#3c50507' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: The LineTokenizer must be set
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:329)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1393)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1134)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:608)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
    at com.di.pos.App.run(App.java:23)
    at com.di.pos.App.main(App.java:15)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'multiResourceReader' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Cannot resolve reference to bean 'flatFileItemReader' while setting bean property 'delegate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flatFileItemReader' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Cannot create inner bean 'com.di.pos.CustomLineMapper#3c50507' of type [com.di.pos.CustomLineMapper] while setting bean property 'lineMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.di.pos.CustomLineMapper#3c50507' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: The LineTokenizer must be set
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:329)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1393)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1134)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:323)
    ... 16 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flatFileItemReader' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Cannot create inner bean 'com.di.pos.CustomLineMapper#3c50507' of type [com.di.pos.CustomLineMapper] while setting bean property 'lineMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.di.pos.CustomLineMapper#3c50507' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: The LineTokenizer must be set
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:282)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:121)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1393)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1134)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:323)
    ... 26 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.di.pos.CustomLineMapper#3c50507' defined in class path resource [spring/batch/jobs/job-read-files.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: The LineTokenizer must be set
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1488)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:271)
    ... 36 more
Caused by: java.lang.IllegalArgumentException: The LineTokenizer must be set
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.batch.item.file.mapping.DefaultLineMapper.afterPropertiesSet(DefaultLineMapper.java:56)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1547)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1485)
    ... 39 more

谁能帮帮我?谢谢。

【问题讨论】:

    标签: java spring spring-boot spring-batch


    【解决方案1】:

    试试这个:

    @Override
    public void setLineTokenizer(LineTokenizer lineTokenizer) {
        super.setLineTokenizer(lineTokenizer);
        this.lineTokenizer = lineTokenizer;
    }
    

    您需要在超类中设置lineTokenizer,就像设置fieldSetMapper 一样。在DefaultLineMapperafterPropertiesSet 方法中,它正在检查它是否有一个lineTokenizer,但它没有一个(不是超类可以访问的)。所以它抛出IllegalArgumentException: 'The LineTokenizer must be set'。

    【讨论】:

      猜你喜欢
      • 2017-04-20
      • 2021-11-22
      • 2017-10-17
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      相关资源
      最近更新 更多