java - 自定义 LineMapper 在 Spring Batch 多文件处理中抛出异常

标签 java spring spring-boot spring-batch

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

作业读取文件.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

谁能帮帮我吗?谢谢。

最佳答案

试试这个:

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

您需要在父类(super class)中设置 lineTokenizer,就像设置 fieldSetMapper 一样。在 DefaultLineMapperafterPropertiesSet 方法中,它正在检查它是否有一个 lineTokenizer,但它没有一个(不是一个可访问的)到 super )。因此它会抛出 IllegalArgumentException:“必须设置 LineTokenizer”。

关于java - 自定义 LineMapper 在 Spring Batch 多文件处理中抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35428283/

相关文章:

java - 将 MariaDB DyanmicColumn 挂接到 Java Spring

java - 如何在 Spring Boot 中创建完全自定义的查询

java - 刷新后的Whitelabel错误页面

java - 如何避免递归函数的 StackOverflowError

java - Spring + Thymeleaf 验证动态生成的字段

带有服务实现的 Spring Autowired 注释

spring - Thymeleaf 和 Spring MVC 当前 Controller 和 Action

java - 求一个数的因数的方法

java - 如何使图像链接在 JtextPane 中工作?

spring - spring boot需要WAS(Websphere Application Server)吗?