Class FileWritingMessageHandler
- All Implemented Interfaces:
org.reactivestreams.Subscriber<Message<?>>,Aware,BeanClassLoaderAware,BeanFactoryAware,BeanNameAware,DisposableBean,InitializingBean,ApplicationContextAware,Lifecycle,Ordered,ExpressionCapable,Orderable,MessageProducer,HeaderPropagationAware,MessageTriggerAction,IntegrationPattern,NamedComponent,IntegrationManagement,ManageableLifecycle,TrackableComponent,MessageHandler,reactor.core.CoreSubscriber<Message<?>>
public class FileWritingMessageHandler extends AbstractReplyProducingMessageHandler implements ManageableLifecycle, MessageTriggerAction
MessageHandler implementation
that writes the Message payload to a
file. If the payload is a File object, it will copy the File to the specified
destination directory. If the payload is a byte array, a String or an
InputStream it will be written directly. Otherwise, the payload type is
unsupported, and an Exception will be thrown.
To append a new-line after each write, set the
appendNewLine flag to 'true'. It is 'false' by default.
If the 'deleteSourceFiles' flag is set to true, the original Files will be
deleted. The default value for that flag is false. See the
setDeleteSourceFiles(boolean) method javadoc for more information.
Other transformers may be useful to precede this handler. For example, any
Serializable object payload can be converted into a byte array by the
PayloadSerializingTransformer.
Likewise, any Object can be converted to a String based on its
toString() method by the
ObjectToStringTransformer.
FileExistsMode.APPEND adds content to an existing file; the file is closed after
each write.
FileExistsMode.APPEND_NO_FLUSH adds content to an existing file and the file
is left open without flushing any data. Data will be flushed based on the
flushInterval or when a message is sent to the
trigger(Message) method, or a
flushIfNeeded
method is called.
- Author:
- Mark Fisher, Iwein Fuld, Alex Peters, Oleg Zhurakousky, Artem Bilan, Gunnar Hillert, Gary Russell, Tony Falabella, Alen Turkovic, Trung Pham
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceFileWritingMessageHandler.FlushPredicateWhen usingFileExistsMode.APPEND_NO_FLUSH, an implementation of this interface is called for each file that has pending data to flush and close whenflushIfNeeded(FlushPredicate)is invoked.static interfaceFileWritingMessageHandler.MessageFlushPredicateWhen usingFileExistsMode.APPEND_NO_FLUSHan implementation of this interface is called for each file that has pending data to flush when a trigger message is received.Nested classes/interfaces inherited from class org.springframework.integration.handler.AbstractReplyProducingMessageHandler
AbstractReplyProducingMessageHandler.RequestHandlerNested classes/interfaces inherited from interface org.springframework.integration.support.management.IntegrationManagement
IntegrationManagement.ManagementOverrides -
Field Summary
Fields inherited from class org.springframework.integration.handler.AbstractMessageProducingHandler
messagingTemplateFields inherited from class org.springframework.integration.context.IntegrationObjectSupport
EXPRESSION_PARSER, loggerFields inherited from interface org.springframework.integration.support.management.IntegrationManagement
METER_PREFIX, RECEIVE_COUNTER_NAME, SEND_TIMER_NAMEFields inherited from interface org.springframework.core.Ordered
HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE -
Constructor Summary
Constructors Constructor Description FileWritingMessageHandler(File destinationDirectory)Constructor which sets thedestinationDirectoryExpressionusing aLiteralExpression.FileWritingMessageHandler(Expression destinationDirectoryExpression)Constructor which sets thedestinationDirectoryExpression. -
Method Summary
Modifier and Type Method Description protected BufferedOutputStreamcreateOutputStream(File fileToWriteTo, boolean append)Create a buffered output stream for the file.protected BufferedWritercreateWriter(File fileToWriteTo, boolean append)Create a buffered writer for the file, for String payloads.protected voiddoInit()voidflushIfNeeded(FileWritingMessageHandler.FlushPredicate flushPredicate)When usingFileExistsMode.APPEND_NO_FLUSHyou can invoke this method to selectively flush and close open files.voidflushIfNeeded(FileWritingMessageHandler.MessageFlushPredicate flushPredicate, Message<?> filterMessage)When usingFileExistsMode.APPEND_NO_FLUSHyou can invoke this method to selectively flush and close open files.StringgetComponentType()Subclasses may implement this method to provide component type information.IntegrationPatternTypegetIntegrationPatternType()Return a pattern type this component implements.protected StringgetTemporaryFileSuffix()protected ObjecthandleRequestMessage(Message<?> requestMessage)Subclasses must implement this method to handle the request Message.booleanisRunning()voidsetAppendNewLine(boolean appendNewLine)If 'true' will append a new-line after each write.voidsetAutoCreateDirectory(boolean autoCreateDirectory)Specify whether to create the destination directory automatically if it does not yet exist upon initialization.voidsetBufferSize(int bufferSize)Set the buffer size to use while writing to files; default 8192.voidsetCharset(String charset)Set the charset name to use when writing a File from a String-based Message payload.voidsetChmod(int chmod)Set the file permissions after uploading, e.g.voidsetChmodOctal(String chmod)String setter for Spring XML convenience.voidsetDeleteSourceFiles(boolean deleteSourceFiles)Specify whether to delete source Files after writing to the destination directory.voidsetExpectReply(boolean expectReply)Specify whether a reply Message is expected.voidsetFileExistsMode(FileExistsMode fileExistsMode)Will set theFileExistsModethat specifies what will happen in case the destination exists.voidsetFileNameGenerator(FileNameGenerator fileNameGenerator)Provide theFileNameGeneratorstrategy to use when generating the destination file's name.voidsetFlushInterval(long flushInterval)Set the frequency to flush buffers whenFileExistsMode.APPEND_NO_FLUSHis being used.voidsetFlushPredicate(FileWritingMessageHandler.MessageFlushPredicate flushPredicate)Set aFileWritingMessageHandler.MessageFlushPredicateto use when flushing files whenFileExistsMode.APPEND_NO_FLUSHis being used.voidsetFlushWhenIdle(boolean flushWhenIdle)Determine whether theflushIntervalapplies only to idle files (default) or whether to flush on that interval after the first write to a previously flushed or new file.voidsetNewFileCallback(BiConsumer<File,Message<?>> newFileCallback)Set the callback to use when creating new files.protected voidsetPermissions(File resultFile)Set permissions on newly written files.voidsetPreserveTimestamp(boolean preserveTimestamp)Set to true to preserve the destination file timestamp.voidsetTemporaryFileSuffix(String temporaryFileSuffix)By default, every file that is in the process of being transferred will appear in the file system with an additional suffix, which by default is ".writing".voidstart()voidstop()voidtrigger(Message<?> message)When usingFileExistsMode.APPEND_NO_FLUSH, you can send a message to this method to flush any file(s) that needs it.Methods inherited from class org.springframework.integration.handler.AbstractReplyProducingMessageHandler
doInvokeAdvisedRequestHandler, getBeanClassLoader, getRequiresReply, handleMessageInternal, hasAdviceChain, onInit, setAdviceChain, setBeanClassLoader, setRequiresReplyMethods inherited from class org.springframework.integration.handler.AbstractMessageProducingHandler
addNotPropagatedHeaders, createOutputMessage, getNotPropagatedHeaders, getOutputChannel, isAsync, messageBuilderForReply, produceOutput, resolveErrorChannel, sendErrorMessage, sendOutput, sendOutputs, setAsync, setNotPropagatedHeaders, setOutputChannel, setOutputChannelName, setSendTimeout, shouldCopyRequestHeaders, shouldSplitOutput, updateNotPropagatedHeadersMethods inherited from class org.springframework.integration.handler.AbstractMessageHandler
handleMessage, onComplete, onError, onNext, onSubscribeMethods inherited from class org.springframework.integration.handler.MessageHandlerSupport
buildSendTimer, destroy, getManagedName, getManagedType, getMetricsCaptor, getOrder, getOverrides, isLoggingEnabled, registerMetricsCaptor, sendTimer, setLoggingEnabled, setManagedName, setManagedType, setOrder, setShouldTrack, shouldTrackMethods inherited from class org.springframework.integration.context.IntegrationObjectSupport
afterPropertiesSet, extractTypeIfPossible, generateId, getApplicationContext, getApplicationContextId, getBeanDescription, getBeanFactory, getBeanName, getChannelResolver, getComponentName, getConversionService, getExpression, getIntegrationProperties, getIntegrationProperty, getMessageBuilderFactory, getTaskScheduler, isInitialized, setApplicationContext, setBeanFactory, setBeanName, setChannelResolver, setComponentName, setConversionService, setMessageBuilderFactory, setPrimaryExpression, setTaskScheduler, toStringMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.springframework.integration.support.management.IntegrationManagement
getThisAsMethods inherited from interface org.springframework.integration.support.context.NamedComponent
getBeanName, getComponentName
-
Constructor Details
-
FileWritingMessageHandler
Constructor which sets thedestinationDirectoryExpressionusing aLiteralExpression.- Parameters:
destinationDirectory- Must not be null- See Also:
FileWritingMessageHandler(Expression)
-
FileWritingMessageHandler
Constructor which sets thedestinationDirectoryExpression.- Parameters:
destinationDirectoryExpression- Must not be null- See Also:
FileWritingMessageHandler(File)
-
-
Method Details
-
setAutoCreateDirectory
public void setAutoCreateDirectory(boolean autoCreateDirectory)Specify whether to create the destination directory automatically if it does not yet exist upon initialization. By default, this value is true. If set to false and the destination directory does not exist, an Exception will be thrown upon initialization.- Parameters:
autoCreateDirectory- true to create the directory if needed.
-
setTemporaryFileSuffix
By default, every file that is in the process of being transferred will appear in the file system with an additional suffix, which by default is ".writing". This can be changed by setting this property.- Parameters:
temporaryFileSuffix- The temporary file suffix.
-
setFileExistsMode
Will set theFileExistsModethat specifies what will happen in case the destination exists. For exampleFileExistsMode.APPENDinstructs this handler to append data to the existing file rather then creating a new file for eachMessage.If set to
FileExistsMode.APPEND, the adapter will also create a real instance of theLockRegistryto ensure that there is no collisions when multiple threads are writing to the same file.Otherwise the LockRegistry is set to
PassThruLockRegistrywhich has no effect.With
FileExistsMode.REPLACE_IF_MODIFIED, if the file exists, it is only replaced if its last modified timestamp is different to the source; otherwise, the write is ignored. ForFilepayloads, the actual timestamp of theFileis compared; for other payloads, theFileHeaders.SET_MODIFIEDis compared to the existing file. If the header is missing, or its value is not aNumber, the file is always replaced. This mode will typically only make sense ifpreserveTimestampis true.- Parameters:
fileExistsMode- Must not be null- See Also:
setPreserveTimestamp(boolean)
-
setExpectReply
public void setExpectReply(boolean expectReply)Specify whether a reply Message is expected. If not, this handler will simply return null for a successful response or throw an Exception for a non-successful response. The default is true.- Parameters:
expectReply- true if a reply is expected.
-
setAppendNewLine
public void setAppendNewLine(boolean appendNewLine)If 'true' will append a new-line after each write. It is 'false' by default.- Parameters:
appendNewLine- true if a new-line should be written to the file after payload is written- Since:
- 4.0.7
-
getTemporaryFileSuffix
-
setFileNameGenerator
Provide theFileNameGeneratorstrategy to use when generating the destination file's name.- Parameters:
fileNameGenerator- The file name generator.
-
setDeleteSourceFiles
public void setDeleteSourceFiles(boolean deleteSourceFiles)Specify whether to delete source Files after writing to the destination directory. The default is false. When set to true, it will only have an effect if the inbound Message has a File payload or aFileHeaders.ORIGINAL_FILEheader value containing either a File instance or a String representing the original file path.- Parameters:
deleteSourceFiles- true to delete the source files.
-
setCharset
Set the charset name to use when writing a File from a String-based Message payload.- Parameters:
charset- The charset.
-
setBufferSize
public void setBufferSize(int bufferSize)Set the buffer size to use while writing to files; default 8192.- Parameters:
bufferSize- the buffer size.- Since:
- 4.3
-
setFlushInterval
public void setFlushInterval(long flushInterval)Set the frequency to flush buffers whenFileExistsMode.APPEND_NO_FLUSHis being used. The interval is approximate; the actual interval will be betweenflushIntervalandflushInterval * 1.33with an average offlushInterval * 1.167.- Parameters:
flushInterval- the interval.- Since:
- 4.3
- See Also:
setFlushWhenIdle(boolean)
-
setFlushWhenIdle
public void setFlushWhenIdle(boolean flushWhenIdle)Determine whether theflushIntervalapplies only to idle files (default) or whether to flush on that interval after the first write to a previously flushed or new file.- Parameters:
flushWhenIdle- false to flush on the interval after the first write to a closed file.- Since:
- 4.3.7
- See Also:
setFlushInterval(long),setBufferSize(int)
-
setFlushPredicate
Set aFileWritingMessageHandler.MessageFlushPredicateto use when flushing files whenFileExistsMode.APPEND_NO_FLUSHis being used. Seetrigger(Message).- Parameters:
flushPredicate- the predicate.- Since:
- 4.3
-
setPreserveTimestamp
public void setPreserveTimestamp(boolean preserveTimestamp)Set to true to preserve the destination file timestamp. If true and the payload is aFile, the payload'slastModifiedtime will be transferred to the destination file. For other payloads, theFileHeaders.SET_MODIFIEDheader "file_setModified" will be used if present and it's aNumber.- Parameters:
preserveTimestamp- the preserveTimestamp to set.- Since:
- 4.3
-
setChmodOctal
String setter for Spring XML convenience.- Parameters:
chmod- permissions as an octal string e.g "600";- Since:
- 5.0
- See Also:
setChmod(int)
-
setChmod
public void setChmod(int chmod)Set the file permissions after uploading, e.g. 0600 for owner read/write. Only applies to file systems that support posix file permissions.- Parameters:
chmod- the permissions.- Throws:
IllegalArgumentException- if the value is higher than 0777.- Since:
- 5.0
-
setNewFileCallback
Set the callback to use when creating new files. This callback will only be called iffileExistsModeisFileExistsMode.APPENDorFileExistsMode.APPEND_NO_FLUSHand new file has to be created. The callback receives the new result file and the message that triggered the handler.- Parameters:
newFileCallback- aBiConsumercallback to be invoked when new file is created.- Since:
- 5.1
-
getComponentType
Description copied from class:IntegrationObjectSupportSubclasses may implement this method to provide component type information.- Specified by:
getComponentTypein interfaceNamedComponent- Overrides:
getComponentTypein classMessageHandlerSupport
-
getIntegrationPatternType
Description copied from interface:IntegrationPatternReturn a pattern type this component implements.- Specified by:
getIntegrationPatternTypein interfaceIntegrationPattern- Overrides:
getIntegrationPatternTypein classAbstractReplyProducingMessageHandler- Returns:
- the
IntegrationPatternTypethis component implements.
-
doInit
protected void doInit()- Overrides:
doInitin classAbstractReplyProducingMessageHandler
-
start
public void start()- Specified by:
startin interfaceLifecycle- Specified by:
startin interfaceManageableLifecycle
-
stop
public void stop()- Specified by:
stopin interfaceLifecycle- Specified by:
stopin interfaceManageableLifecycle
-
isRunning
public boolean isRunning()- Specified by:
isRunningin interfaceLifecycle- Specified by:
isRunningin interfaceManageableLifecycle
-
handleRequestMessage
Description copied from class:AbstractReplyProducingMessageHandlerSubclasses must implement this method to handle the request Message. The return value may be a Message, a MessageBuilder, or any plain Object. The base class will handle the final creation of a reply Message from any of those starting points. If the return value is null, the Message flow will end here.- Specified by:
handleRequestMessagein classAbstractReplyProducingMessageHandler- Parameters:
requestMessage- The request message.- Returns:
- The result of handling the message, or
null.
-
setPermissions
Set permissions on newly written files.- Parameters:
resultFile- the file.- Throws:
IOException- any exception.- Since:
- 5.0
-
createWriter
protected BufferedWriter createWriter(File fileToWriteTo, boolean append) throws FileNotFoundExceptionCreate a buffered writer for the file, for String payloads.- Parameters:
fileToWriteTo- the file.append- true if we are appending.- Returns:
- the writer.
- Throws:
FileNotFoundException- if the file does not exist.- Since:
- 4.3.8
-
createOutputStream
protected BufferedOutputStream createOutputStream(File fileToWriteTo, boolean append) throws FileNotFoundExceptionCreate a buffered output stream for the file.- Parameters:
fileToWriteTo- the file.append- true if we are appending.- Returns:
- the stream.
- Throws:
FileNotFoundException- if not found.- Since:
- 4.3.8
-
trigger
When usingFileExistsMode.APPEND_NO_FLUSH, you can send a message to this method to flush any file(s) that needs it. By default, the payload must be a regular expression (StringorPattern) that matches the absolutePath of any in-process files. However, if a customFileWritingMessageHandler.MessageFlushPredicateis provided, the payload can be of any type supported by that implementation.- Specified by:
triggerin interfaceMessageTriggerAction- Parameters:
message- the message.- Since:
- 4.3
-
flushIfNeeded
When usingFileExistsMode.APPEND_NO_FLUSHyou can invoke this method to selectively flush and close open files. For each open file the suppliedFileWritingMessageHandler.MessageFlushPredicate.shouldFlush(String, long, long, Message)method is invoked and if true is returned, the file is flushed.- Parameters:
flushPredicate- theFileWritingMessageHandler.FlushPredicate.- Since:
- 4.3
-
flushIfNeeded
public void flushIfNeeded(FileWritingMessageHandler.MessageFlushPredicate flushPredicate, Message<?> filterMessage)When usingFileExistsMode.APPEND_NO_FLUSHyou can invoke this method to selectively flush and close open files. For each open file the suppliedFileWritingMessageHandler.MessageFlushPredicate.shouldFlush(String, long, long, Message)method is invoked and if true is returned, the file is flushed.- Parameters:
flushPredicate- theFileWritingMessageHandler.MessageFlushPredicate.filterMessage- an optional message passed into the predicate.- Since:
- 4.3
-