Ausgabe
Ich habe einen Remote-FTP-Server, auf dem ich den FtpStreamingMessageSource Inbound Channel Adapter gemountet habe, und jetzt muss ich Dateien mithilfe von Regex nach Dateinamen filtern und an die entsprechenden Kanäle weiterleiten, um einen Batch-Job zu starten. Die offizielle Dokumentation enthält PayloadTypeRouter, HeaderValueRouter, aber sie sind für diese Aufgabe nicht geeignet. Ich kann mit Filtern spielen, aber dann muss ich mehrere Inbound Channel Adapter für jede Datei mit spezifischem Filter schreiben. Ist das normal oder gibt es eine bessere Lösung?
Beispiel: Ich habe A.csv-, B.csv-, C.csv-, D.csv-Dateien auf FTP. Nach dem Lesen muss ich A.csv an Kanal A, B.csv an Kanal B und so weiter weiterleiten.
Unten ist die aktuelle Arbeitslösung , fühlen Sie sich frei zu kommentieren und zu korrigieren
@Override
protected Object doTransform(Message<?> message) {
IntegrationMessageHeaderAccessor accessor = new IntegrationMessageHeaderAccessor(message);
MessageBuilder messageBuilder = MessageBuilder.fromMessage(message);
String fileName = accessor.getHeader("file_remoteFile").toString();
if(fileName.contains("file_name1")){
messageBuilder.setHeader("channel", "channel1");
} else if (fileName.contains("file_name2")){
messageBuilder.setHeader("channel", "channel2");
} else if(fileName.contains("file_name3")) {
messageBuilder.setHeader("channel", "channel3");
} else if (fileName.contains("file_name4")){
messageBuilder.setHeader("channel", "channel4");
}
return messageBuilder.build();
}
Und hier ist Routing
@Bean
@org.springframework.integration.annotation.Transformer(inputChannel = CHANNEL_STREAMED_DATA, outputChannel = CHANNEL_DATA)
public CustomTransformer customTransformer() {
return new CustomTransformer();
}
@ServiceActivator(inputChannel = CHANNEL_DATA)
@Bean
public HeaderValueRouter router() {
HeaderValueRouter router = new HeaderValueRouter("channel");
router.setChannelMapping("channel1", "channelA");
router.setChannelMapping("channel2", "channelB");
return router;
}
Lösung
Nun, das haben Sie bereits file_remoteFile
mit allen Informationen, die Sie für das Routing benötigen.
Verwenden Sie @Router
stattdessen eine einfache POJO-Methode:
@Router(inputChannel = CHANNEL_STREAMED_DATA)
String routeByRemoteFile(@Header(FileHeaders.REMOTE_FILE) String remoteFile) {
...
}
Und geben Sie einen entsprechenden Kanalnamen gemäß Ihrer Dateinamen-Übereinstimmungslogik zurück.
Weitere Informationen finden Sie in den Dokumenten: https://docs.spring.io/spring-integration/docs/current/reference/html/message-routing.html#router-annotation
Beantwortet von – Artem Bilan
Antwort geprüft von – Robin (FixError Admin)