【问题标题】:How to call appropriate Item Processor for different records?如何为不同的记录调用适当的项目处理器?
【发布时间】:2020-02-10 04:29:26
【问题描述】:

我有一个包含不同记录(页眉、记录和页脚)的平面文件

HR,...
RD,...
FR,...

项目阅读器

    @Bean
    @StepScope
    public FlatFileItemReader reader(@Value("#{jobParameters['inputFileName']}") String inputFileName) {
        FlatFileItemReader reader = new FlatFileItemReader();
        reader.setResource(new FileSystemResource(inputFileName));
        reader.setLineMapper(patternLineMapper());
        return reader;
    }
    @Bean
    public LineMapper patternLineMapper() {
        PatternMatchingCompositeLineMapper patternLineMapper = new PatternMatchingCompositeLineMapper<>();
        tokenizers = new HashMap<String, LineTokenizer>();
        try {
            tokenizers.put("HR*", headerLineTokenizer());
            tokenizers.put("RD*", recordLineTokenizer());
            tokenizers.put("FR*", footerLineTokenizer());
        } catch (Exception e) {
            e.printStackTrace();
        }
        fieldSetMappers = new HashMap<String, FieldSetMapper>();
        fieldSetMappers.put("HR*", new HeaderFieldSetMapper());
        fieldSetMappers.put("RD*", new RecordFieldSetMapper());
        fieldSetMappers.put("FR*", new FooterFieldSetMapper());
        patternLineMapper.setTokenizers(tokenizers);
        patternLineMapper.setFieldSetMappers(fieldSetMappers);
        return patternLineMapper;
    }

他们工作正常,弹簧批处理为每条记录调用适当的阅读器问题是当涉及到项目处理器时我想使用相同的方法我得到java.lang.ClassCastException因为弹簧批处理尝试映射域对象[从阅读器返回] 到java.lang.String

项目处理器

    @Bean
    @StepScope
    public ItemProcessor processor() {

        ClassifierCompositeItemProcessor processor = new ClassifierCompositeItemProcessor();
        PatternMatchingClassifier<ItemProcessor> classifier = new PatternMatchingClassifier<>();
        Map<String, ItemProcessor> patternMap = new HashMap<>();
        patternMap.put("HR*", new HeaderItemProcessor());
        patternMap.put("RD*", new RecordItemProcessor());
        patternMap.put("FR*", new FooterItemProcessor());
        classifier.setPatternMap(patternMap);
        processor.setClassifier(classifier);
        return processor;
    }

我也使用了BackToBackPatternClassifier,但事实证明它有一个错误,当我使用像ItemWriter&lt;Object&gt; 这样的泛型时,我得到一个异常无法打开文件。问题是 如何使 ItemProcessor 处理从 Reader 返回的不同记录类型?

【问题讨论】:

    标签: spring-boot spring-batch


    【解决方案1】:

    您的问题是您在ClassifierCompositeItemProcessor 中使用的分类器基于字符串模式而不是类型。真正应该发生的事情是这样的:

    阅读器根据输入模式返回特定类型的项目,例如:

    • HR* -> HRType
    • RD* -> RDType
    • FR* -> FRType

    这基本上是您在阅读器方面所做的。现在在处理方面,处理器将接收HRTypeRDTypeFRType 类型的对象。所以分类器不应该基于String作为输入类型,而是基于item类型,比如:

        Map<Object, ItemProcessor> patternMap = new HashMap<>();
        patternMap.put(HRType.class, new HeaderItemProcessor());
        patternMap.put(RDType.class, new RecordItemProcessor());
        patternMap.put(FRType.class, new FooterItemProcessor());
    

    此分类器使用 Object 类型,因为您的 ItemReader 返回原始类型。我建议在分类器中使用原始类型和Object 类型。你应该做的是:

    1. 为您的项目创建一个基类并为每种类型创建一个特定类
    2. 让读者返回&lt;? extends BaseClass&gt;类型的项目
    3. 在您的ClassifierCompositeItemProcessor 中使用org.springframework.classify.SubclassClassifier

    【讨论】:

    • 我想确定的是,我不能将PatternMatchingClassifier 与类型对象一起使用,因为它期望得到java.lang.String@Mahmoud
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    相关资源
    最近更新 更多