Метод encode
компонента fileProcessor
отвечает за кодирование видеофайла. Если он сталкивается с проблемой, файл не следует удалять, иначе, если все будет хорошо, его можно удалить. Прямо сейчас единственный способ сохранить поток Message
без изменения полезной нагрузки - сделать метод encode
void
. Мне нужно вернуть некоторую "заголовочную" информацию, хотя SI
впоследствии может удалить файл. Я попытался использовать MessageBuilder
для создания Message<File>
и вернуть его, но когда он поступит в следующий канал, он был завернут, и в Message
есть Message
, поэтому мое выражение не работает, чтобы вызвать удаление.
Я предполагаю, что могу использовать обернутое Message
и выкапывать один уровень в графе объектов, но это кажется неуклюжим.
Каков наилучший подход к привязке к некоторой возвращаемой ценности, не разрушая исходную полезную нагрузку Message и не загрязняя мой метод кодирования POJO каналами SI и отправкой?
Вот моя конфигурация:
<!-- ########################## -->
<!-- ### Encoding ### -->
<!-- ########################## -->
<file:inbound-channel-adapter
directory="${paths.encode}"
channel="encodeChannel"
filename-regex="${encode.regex}"
prevent-duplicates="false">
<int:poller fixed-rate="5000"/>
</file:inbound-channel-adapter>
<int:service-activator
input-channel="encodeChannel"
output-channel="encodeResultChannel"
ref="fileProcessor"
method="encode">
</int:service-activator>
<!-- This is where I'm having trouble. -->
<!-- I don't expect this router to work. -->
<int:router
input-channel="encodeResultChannel"
expression="payload">
<int:mapping value="true" channel="encodeDeleteChannel"/>
<int:mapping value="false" channel="stdout"/>
</int:router>
<int:service-activator
input-channel="encodeDeleteChannel"
expression="payload.delete()"
output-channel="stdout">
</int:service-activator>
<stream:stdout-channel-adapter
id="stdout"
append-newline="true" />
редактировать:
Я использую:
<properties>
<spring-framework.version>3.2.3.RELEASE</spring-framework.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
<version>1.1.0.BUILD-SNAPSHOT</version>
</dependency>
edit2:
здесь обновленная конфигурация
<!-- ########################## -->
<!-- ### Encoding ### -->
<!-- ########################## -->
<file:inbound-channel-adapter
directory="${paths.encode}"
channel="filePickupChannel"
filename-regex="${encode.regex}"
prevent-duplicates="false">
<int:poller fixed-rate="5000"/>
</file:inbound-channel-adapter>
<int:header-enricher
input-channel="filePickupChannel"
output-channel="encodeChannel">
<int:header name="origFile" expression="payload"/>
</int:header-enricher>
<int:service-activator
input-channel="encodeChannel"
output-channel="encodeResultChannel"
ref="fileProcessor"
method="encode">
</int:service-activator>
<int:router
input-channel="encodeResultChannel"
ignore-send-failures="false"
default-output-channel="stdout"
expression="payload">
<int:mapping value="true" channel="encodeDeleteChannel"/>
<int:mapping value="false" channel="stdout"/>
</int:router>
<int:service-activator
input-channel="encodeDeleteChannel"
expression="headers['origFile'].delete()"
output-channel="stdout">
</int:service-activator>
Какую версию Spring Integration и Spring Framework вы используете?
Как выглядит подпись fileProcessor.encode()
?
Вы не должны получать вложенное Message<?>
, У AbstractReplyProducingMessageHandler
есть следующая логика...
private Message<?> createReplyMessage(Object reply, MessageHeaders requestHeaders) {
AbstractIntegrationMessageBuilder<?> builder = null;
if (reply instanceof Message<?>) {
if (!this.shouldCopyRequestHeaders()) {
return (Message<?>) reply;
}
builder = this.getMessageBuilderFactory().fromMessage((Message<?>) reply);
}
...
if (this.shouldCopyRequestHeaders()) {
builder.copyHeadersIfAbsent(requestHeaders);
}
return builder.build();
}
Итак, если вы вернете Message<?>
Ваше сообщение будет возвращено (усилено с любыми входящими заголовками, которые вы не установили).
Используете Spring Integration 3.0.x с Spring Framework 4.0.x? Если это так, вам нужно быть осторожным, чтобы вернуть сообщение org.springframework.integration
, а не сообщение org.springframework.messaging
.
Если вы org.springframework.messaging
сообщение org.springframework.messaging
, Spring Integration действительно будет org.springframework.messaging
сообщение интеграции Spring.
Классы основных сообщений были перенесены в модуль Spring spring-messaging
в Spring Framework 4.0, поэтому их можно использовать для веб-узлов, STOMP и т.д.
Spring Integration 4.0.x теперь также использует эти классы, поэтому вы не увидите их на пути к классам; избегая путаницы. При использовании Spring Integration 3.0.x с Spring Framework 4.0.x вам нужно проявлять большую осторожность, чтобы использовать нужные классы.
В общем, однако, мы не рекомендуем добавлять в свой код классы инфраструктуры (такие как Message<?>
), Вместо этого использовать POJO, и структура будет заботиться о деталях сообщений...
boolean encode(File file) {...}
Если вам нужно получить доступ к полезной нагрузке после кодирования, подумайте о том, чтобы продвигать ее в заголовок заранее.
<int:header-enricher ...>
<int:header name="origFile" expression="payload" />
</int:header-enricher>
Затем используйте expression="headers['origFile'].delete()
после кодирования.
РЕДАКТИРОВАТЬ:
Или верните файл (так что он станет новой полезной нагрузкой) при успешном завершении, а при ошибке возвратите null
или выбросите исключение, и поток нисходящего потока не будет выполнен.