Spring集成拆分和循环

时间:2017-04-20 18:29:29

标签: spring spring-integration

我是Spring Integration的新手,拥有一个接受文件作为输入的应用程序,并根据每个文件的内容对这些文件进行一些特定的处理。

当文件进来时,我有一个路由器决定是否输入“A”,“B”或“ZIP”文件并将其路由到适当的频道。在ZIP文件的情况下,我有一个拆分器,它解压缩zip文件并将结果发送回路由器,以确定zip中的文件类型是A,B还是嵌套的ZIP文件。

还指定了一个处理文件解析错误的错误通道。

XML的相关部分如下所示:

<?xml version="1.0" encoding="UTF-8"?>

...
...

<int:channel id="checkFile" />
<int:channel id="A" />
<int:channel id="B" />
<int:channel id="ZIP" />

<!-- Route the file to the appropriate parser - A, B, or ZIP -->
<int:router input-channel="checkFile" ref="fileTypeIdentifier" method="identifyType" />

<!-- If we have a ZIP file, extract the contents and process each one individually -->
<int:splitter input-channel="ZIP" output-channel="checkFile" ref="extractor" />

<!-- Parse file type A -->
<int:chain input-channel="A" output-channel="Done">
    ...
    ...
</int:chain>

<!-- Parse file type B -->
<int:chain input-channel="B" output-channel="Done">
    ...
    ...
</int:chain>

...
...

如果我的输入文件是包含file1.txt和file2.txt的myfile.zip,则路由器正确地将myfile.zip路由到拆分器,该拆分器成功提取file1.txt和file2.txt(并返回这2个文件)。 / p>

如果我在解析file1.txt时出错,我仍然想尝试解析file2.txt。所以在阅读Spring Integration: Splitter exception causes subsequent messages to abort之后,我尝试将我的“checkFile”频道设为队列频道,现在发生的是我传入myfile.zip,它被路由到“ZIP”频道,成功返回“file1.txt”和“ file2.txt“,然后路由器继续用”myfile.zip“无限循环调用。

使用执行程序通道而不是队列通道会导致类似的问题。

如何让我的流程解压缩文件并单独处理其内容,同时允许zip中的一个或多个文件失败而不会使整个作业失败?

1 个答案:

答案 0 :(得分:0)

这里可能会占用很多位置,但无论如何我都会试着发布它:

<bean id="fileTypeIdentifier" class="org.springframework.integration.splitter.So43527224Tests$FileTypeIdentifier"/>

<bean id="fileParser" class="org.springframework.integration.splitter.So43527224Tests$FileParser"/>

<int:channel id="checkFile">
    <int:queue/>
</int:channel>

<!-- Route the file to the appropriate parser - A, B, or ZIP -->
<int:router input-channel="checkFile" ref="fileTypeIdentifier" method="identifyType">
    <int:poller fixed-delay="1000"/>
</int:router>

<!-- If we have a ZIP file, extract the contents and process each one individually -->
<int:splitter input-channel="ZIP" output-channel="checkFile"/>

<!-- Parse file type A -->
<int:service-activator input-channel="A" output-channel="nullChannel"
                       ref="fileParser" method="parseFileA"/>

<!-- Parse file type B -->
<int:service-activator input-channel="B" output-channel="nullChannel"
                       ref="fileParser" method="parseFileB"/>

测试班:

@RunWith(SpringRunner.class)
@DirtiesContext
public class So43527224Tests {

    @Autowired
    private MessageChannel checkFile;

    @Test
    public void testSo43527224() throws InterruptedException {
        this.checkFile.send(new GenericMessage<>(2));
        this.checkFile.send(new GenericMessage<>(3));
        this.checkFile.send(new GenericMessage<>(Collections.singletonList(4)));
        this.checkFile.send(new GenericMessage<>(Collections.singletonList(5)));

        List<Object> zip = new ArrayList<>();

        zip.add(6);
        zip.add(7);

        List<Integer> nestedZip = new ArrayList<>();
        nestedZip.add(9);
        nestedZip.add(8);
        zip.add(nestedZip);

        this.checkFile.send(new GenericMessage<>(zip));

        Thread.sleep(10000);
    }

    private static class FileTypeIdentifier {

        public String identifyType(Object payload) {
            if (payload instanceof List) {
                System.out.println("ZIP: " + payload);
                return "ZIP";
            }
            else if (Integer.class.cast(payload) % 2 == 0) {
                return "A";
            }
            else {
                return "B";
            }
        }

    }

    private static class FileParser {

        public String parseFileA(Object payload) {
            throw new RuntimeException("intentional: A is always bad: " + payload);
        }

        public void parseFileB(Object payload) {
            System.out.println("Good file B: " + payload);
        }

    }

}

日志看起来像这样(没有堆栈跟踪):

Caused by: java.lang.RuntimeException: intentional: A is always bad: 2
Good file B: 3
ZIP: [4]
ZIP: [5]
ZIP: [6, 7, [9, 8]]
Caused by: java.lang.RuntimeException: intentional: A is always bad: 4
Good file B: 5
Caused by: java.lang.RuntimeException: intentional: A is always bad: 6
Good file B: 7
ZIP: [9, 8]
Good file B: 9
Caused by: java.lang.RuntimeException: intentional: A is always bad: 8

所以,正如我之前所说:这里还有其他东西没有显示,以确定循环的原因。

您始终可以为DEBUG类别启用org.springframework.integration来分析您的消息在流程中的传输方式。