Интеграция Springboot — Доступ к заголовкам в обработчике сообщений

#java #spring-boot #spring-integration

Вопрос:

Я пытаюсь переместить файл в определенное место на основе заголовка, присутствующего в потоке

 @Bean
public IntegrationFlow configureFileFlow(
        @Value("${fileSource}") String sourcePath,
        @Value("${fileTarget}") String targetPath
) {
    return IntegrationFlows.from(
            getDataSource(sourcePath),
            conf -> conf.poller(Pollers.fixedDelay(pollerDelay))
    )
            .enrichHeaders(eh -> eh.header("targetPath", targetPath)) //<-- this is the target
            .enrichHeaders(eh -> eh.headerExpression("originalFileName", "payload.getName"))
            .channel("processFile.input")
            .get();
}
 

при обработке файла, после выполнения всех необходимых процедур, я вызываю компонент следующим образом

 .handle(backupFile())
 

что вызывает

 @Bean
public MessageHandler backupFile() {
    FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(targetPath));
    handler.setAutoCreateDirectory(true);
    handler.setFileExistsMode(FileExistsMode.REPLACE_IF_MODIFIED);
    handler.setExpectReply(false);
    handler.setDeleteSourceFiles(true);
    return handler;
}
 

Как можно было бы настроить targetPath динамическую настройку на основе того, что задано в заголовках, пожалуйста? Я не могу просто передать его в качестве параметра, так как это компонент, и я хотел бы избежать создания дополнительных компонентов только ради извлечения строки. Кроме того, повторное использование a @Value во второй части потока кажется излишним, поскольку оно уже является частью самого сообщения в заголовках.

Существует несколько типов обрабатываемых файлов, каждый из которых имеет свой собственный IntegrationFlow источник, но эта часть, где он получает «резервную копию», должна быть общей для всех них. backupFile Компонент в основном должен содержать две информации — сам файл в качестве полезной нагрузки и информацию из заголовков о том, где его хранить.

Спасибо!

Ответ №1:

Смотрите другой конструктор:

 /**
 * Constructor which sets the {@link #destinationDirectoryExpression}.
 * @param destinationDirectoryExpression Must not be null
 * @see #FileWritingMessageHandler(File)
 */
public FileWritingMessageHandler(Expression destinationDirectoryExpression) {
 

Итак, используя аналогичное выражение SpEL, которое у вас есть выше, вы можете сделать что-то вроде:

 new FileWritingMessageHandler(new SpelExpressionParser().parseExpression("headers.targetPath"));
 

Также смотрите org.springframework.integration.file.dsl.Files.outboundAdapter() более высокоуровневый Java DSL API по этому FileWritingMessageHandler поводу .

Комментарии:

1. Замечательное решение, именно то, что мне было нужно. Большое спасибо!