2016-09-19 2 views
1

Я пытаюсь написать простой тест переименования файлов на месте с помощью FileWritingMessageHandler, однако я не могу понять, как правильно указать целевой целевой каталог.Переименовать файл на месте с помощью Spring Integration FileWritingMessageHandler

Поскольку я рекурсивно просматриваю дерево каталогов, мне в конечном итоге хотелось бы просто прочитать родительский путь из полезной нагрузки файла и переименовать его с помощью FileNameGenerator, но это не работает.

«payload.name» в DefaultFileNameGenerator разрешает корректно, но «payload.path» этого не делает.

Как правильно определить местоположение исходного файла и использовать его в обработчике?

Редактировать

Вот адаптер канала, который сканирует файлы. Для достижения рекурсивного сканирования мне пришлось использовать .setUseWatchService(true).

@Bean 
@InboundChannelAdapter(channel = "sourceFileChannel", poller =  @Poller(fixedRate = "5000", maxMessagesPerPoll = "-1")) 
public MessageSource<File> sourceFiles() { 

CompositeFileListFilter<File> filters = new CompositeFileListFilter<>(); 
filters.addFilter(new SimplePatternFileListFilter(sourceFilenamePattern)); 
filters.addFilter(persistentFilter()); 

FileReadingMessageSource source = new FileReadingMessageSource(); 
source.setAutoCreateDirectory(true); 
source.setDirectory(new File(sourceDirectory)); 
source.setFilter(filters); 
source.setUseWatchService(true); 

return source; 
} 

UPDATE

Артем помог мне понять мою ошибку.

Мне удалось достичь желаемого результата с помощью SpelExpressionParser, как указано в Artem.

Ключевое существо:

new SpelExpressionParser().parseExpression("payload.parent")

Где "payload.parent" решает файл родительского пути правильно.

@Bean 
@ServiceActivator(inputChannel = "processingFileChannel") 
public MessageHandler copyFileForProcessingOutboundChannelAdapter() { 

    FileWritingMessageHandler adapter = new FileWritingMessageHandler(new SpelExpressionParser().parseExpression("payload.parent")); 
    adapter.setDeleteSourceFiles(false); 
    adapter.setAutoCreateDirectory(true); 
    adapter.setExpectReply(false); 
    adapter.setFileNameGenerator(processingFileNameGenerator()); 

    return adapter; 
} 

@Bean 
public DefaultFileNameGenerator processingFileNameGenerator() { 
    DefaultFileNameGenerator defaultFileNameGenerator = new DefaultFileNameGenerator(); 
    defaultFileNameGenerator.setExpression("'p_' + payload.name"); 
    return defaultFileNameGenerator; 
} 
+0

Не могли бы вы поделиться с адаптером 'source', чтобы выяснить, как вы« рекурсивно сканируете »? –

+0

Возможно, ваша проблема здесь: https://jira.spring.io/browse/INT-832 –

ответ

2

'payload.name' в DefaultFileNameGenerator решает правильно, но 'payload.path' нет.

Ну, я не уверен, что должно быть в вашем случае, но для меня это всегда возвращает полный, абсолютный путь к исходному файлу, включая корневую директорию для сканирования.

Поскольку вы его там как sourceDirectory, как собирается использовать его в processingFileNameGenerator разъединить корневой каталог от цели path использовать? Например, если мой корневой каталог равен /root, и я получаю файл из подкаталога /root/foo/my_file.txt, я мог бы сделать payload.path.replaceFirst('/root', ''). Так что в итоге у меня только /foo/my_file.txt.

По крайней мере, это то, что я собираюсь сделать в этом JIRA для заполнения FileHeaders.FILENAME с относительным путем от предоставленного directory для сканирования.

UPDATE

Oh! Понимаю. Нет, это не сработает. См. FileWritingMessageHandler ctors. String один раз принимает статический целевой каталог. Корень для нашего дела. Код вроде new LiteralExpression("payload.path") тоже не будет работать. См. LiteralExpression JavaDocs.Это просто вариант Expression, который всегда возвращает то же статическое значение. В вашем случае это payload.path.

Если вы действительно собираетесь оценить от входящего Message, вы должны использовать new SpeLexpressionParser().parseExpression("payload.path"). Но, как я уже говорил, он возвращает абсолютный путь для любого файла в подкаталогах.

+0

Спасибо Артем, я попробую этот подход. Я даже попытался представить Transformer для добавления нового заголовка PARENT в (File) message.getPayload()). GetParent(), но все же в ServiceActivator copyFileForProcessingOutboundChannelAdapter() строка FileWritingMessageHandler adapter = new FileWritingMessageHandler ("headers .parent "); просто создает новый каталог с именем «headers.parent» по сравнению с существующим родительским каталогом из значения заголовка. – rcurrie

+1

Пожалуйста, найдите «EDIT» в моем ответе. –

+0

Спасибо, Артем, что мне нужно! – rcurrie