如何在spring批处理中读取ini文件(key = value)

时间:2014-06-16 12:20:05

标签: java spring file spring-batch ini

我想创建一个批处理,使用Spring批处理从ini文件中读取数据并将数据保存在数据库中但是当我查询org.springframework.batch.item.file.FlatFileItemReader类时,我没有找到从ini文件中解析数据的方法,我尝试将ini4j API与spring批处理相结合,但没有结果

我的ini文件:

 [Cat]
    a=1
    b= 2
    c= 3
    d= 4
    e= 5
    f= 6
    [Cat2]
     a=11
    b= 21
    c= 31
    d= 41
    e= 51
    f= 61

1 个答案:

答案 0 :(得分:1)

您可以做的是定义一个包含委托ItemStreamReader的{​​{1}},这只是ItemStreamReader使用FlatFileItemReader作为行映射器。在PatternMatchingCompositeLineMapper中,循环读取委托中的行,如果该行是ItemStreamReader域对象的实例,则将其添加到Property域对象的列表中。 Section允许你做的是检查模式匹配的行,并将其传递给右边的tokenizer和fieldSetMapper。

这样做可以让您将多行读入一个包含PatternMatchingCompositeLineMapper的{​​{1}}域对象。

Section

对于自定义List<Property>,您可以这样做。您可以看到读数被委托给另一个读者,您将在稍后定义

public class Section {

    private String name;
    private List<Property> properties;
    // getters and setters

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(name);
        for (Property prop: properties) {
            sb.append("," + prop.getKey() + "=" + prop.getValue());
        }
        return sb.toString();
    }
}

public class Property {

    private String key;
    private String value;
    // getters and setters
}

然后在您的配置中,使用ItemStreamReader

定义deleagte阅读器
import java.util.ArrayList;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;

public class IniFileItemReader implements ItemStreamReader<Object> {

    private Object curItem = null;
    private ItemStreamReader<Object> delegate;

    @Override
    public Object read() throws Exception, UnexpectedInputException,
            ParseException, NonTransientResourceException {
        if (curItem == null) {
            curItem = (Section) delegate.read();
        }

        Section section = (Section) curItem;
        curItem = null;

        if (section != null) {
            section.setProperties(new ArrayList<Property>());

            while (peek() instanceof Property) {
                section.getProperties().add((Property) curItem);
                curItem = null;
            }
        }
        return section;
    }

    private Object peek() throws Exception {
        if (curItem == null) {
            curItem = delegate.read();
        }
        return curItem;
    }

    public void setDelegate(ItemStreamReader<Object> delegate) {
        this.delegate = delegate;
    }

    @Override
    public void close() throws ItemStreamException {
        delegate.close();
    }

    @Override
    public void open(ExecutionContext arg0) throws ItemStreamException {
        delegate.open(arg0);
    }

    @Override
    public void update(ExecutionContext arg0) throws ItemStreamException {
        delegate.update(arg0);
    }
}

您看到我也使用了自定义PatternMatchingCompositeLineMapper。我可能只能使用<bean id="inputFile" class="org.springframework.core.io.FileSystemResource" scope="step"> <constructor-arg value="#{jobParameters[inputFile]}"></constructor-arg> </bean> <bean id="sectionFileReader" class="com.underdogdevs.springbatch.reader.IniFileItemReader"> <property name="delegate" ref="trueSectionFileReader"></property> </bean> <bean id="trueSectionFileReader" class="org.springframework.batch.item.file.FlatFileItemReader"> <property name="lineMapper"> <bean class="org.springframework.batch.item.file.mapping.PatternMatchingCompositeLineMapper"> <property name="tokenizers"> <map> <entry key="[*" value-ref="sectionLineTokenizer"> </entry> <entry key="*" value-ref="propertyLineTokenizer"></entry> </map> </property> <property name="fieldSetMappers"> <map> <entry key="[*" value-ref="sectionFieldSetMapper"> </entry> <entry key="*" value-ref="propertyFieldSetMapper"> </entry> </map> </property> </bean> </property> <property name="resource" ref="inputFile"></property> </bean> <bean id="sectionLineTokenizer" class="com.underdogdevs.springbatch.tokenizer.SectionLineTokenizer"> </bean> <bean id="sectionFieldSetMapper" class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper"> <property name="prototypeBeanName" value="section"></property> </bean> <bean id="section" class="com.underdogdevs.springbatch.domain.Section" scope="prototype"> </bean> <bean id="propertyLineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"> <property name="delimiter" value="="></property> <property name="names" value="key,value"></property> </bean> <bean id="propertyFieldSetMapper" class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper"> <property name="prototypeBeanName" value="property"></property> </bean> <bean id="property" class="com.underdogdevs.springbatch.domain.Property" scope="prototype"> </bean> ,但是当我意识到它时,我已经定义了这个类

LineTozenizer

使用以下作家和作业

DelimitedLineTokenizer

并使用此ini文件

import org.springframework.batch.item.file.transform.DefaultFieldSetFactory;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.batch.item.file.transform.FieldSetFactory;
import org.springframework.batch.item.file.transform.LineTokenizer;

public class SectionLineTokenizer implements LineTokenizer {

    private final String nameField = "name";
    private final FieldSetFactory fieldSetFactory = new DefaultFieldSetFactory();

    @Override
    public FieldSet tokenize(String line) {
        String name = line.replaceAll("\\[", "").replaceAll("\\]", "").trim();

        return fieldSetFactory.create(new String[] { name },
                new String[] { nameField });
    }
}

我得到以下输出,这是我<bean id="outputFile" class="org.springframework.core.io.FileSystemResource" scope="step"> <constructor-arg value="#{jobParameters[outputFile]}"></constructor-arg> </bean> <bean id="outputFileWriter" class="org.springframework.batch.item.file.FlatFileItemWriter"> <property name="resource" ref="outputFile"></property> <property name="lineAggregator"> <bean class="org.springframework.batch.item.file.transform.PassThroughLineAggregator"> </bean> </property> </bean> <batch:step id="outputStep"> <batch:tasklet> <batch:chunk commit-interval="10" reader="sectionFileReader" writer="outputFileWriter"> <batch:streams> <batch:stream ref="sectionFileReader" /> <batch:stream ref="trueSectionFileReader" /> </batch:streams> </batch:chunk> </batch:tasklet> </batch:step> <batch:job id="iniJob"> <batch:step id="step1" parent="outputStep"></batch:step> </batch:job> [Cat] a=1 b=2 c=3 d=4 e=5 f=6 [Cat2] a=11 b=21 c=31 d=41 e=51 f=61 中的格式

toString()