public class FileWritingMessageHandler
extends org.springframework.integration.handler.AbstractReplyProducingMessageHandler
implements org.springframework.context.Lifecycle, org.springframework.integration.handler.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.
Modifier and Type | Class and Description |
---|---|
static interface |
FileWritingMessageHandler.FlushPredicate
When using
FileExistsMode.APPEND_NO_FLUSH , an implementation of this
interface is called for each file that has pending data to flush and close when
flushIfNeeded(FlushPredicate) is invoked. |
static interface |
FileWritingMessageHandler.MessageFlushPredicate
When using
FileExistsMode.APPEND_NO_FLUSH
an implementation of this interface is called for each file that has pending data
to flush when a trigger message is received. |
messagingTemplate
EXPRESSION_PARSER, logger
Constructor and Description |
---|
FileWritingMessageHandler(org.springframework.expression.Expression destinationDirectoryExpression)
Constructor which sets the
destinationDirectoryExpression . |
FileWritingMessageHandler(java.io.File destinationDirectory)
Constructor which sets the
destinationDirectoryExpression using
a LiteralExpression . |
Modifier and Type | Method and Description |
---|---|
protected java.io.BufferedOutputStream |
createOutputStream(java.io.File fileToWriteTo,
boolean append)
Create a buffered output stream for the file.
|
protected java.io.BufferedWriter |
createWriter(java.io.File fileToWriteTo,
boolean append)
Create a buffered writer for the file, for String payloads.
|
protected void |
doInit() |
void |
flushIfNeeded(FileWritingMessageHandler.FlushPredicate flushPredicate)
When using
FileExistsMode.APPEND_NO_FLUSH you can invoke this method to
selectively flush and close open files. |
void |
flushIfNeeded(FileWritingMessageHandler.MessageFlushPredicate flushPredicate,
org.springframework.messaging.Message<?> filterMessage)
When using
FileExistsMode.APPEND_NO_FLUSH you can invoke this method to
selectively flush and close open files. |
protected java.lang.String |
getTemporaryFileSuffix() |
protected java.lang.Object |
handleRequestMessage(org.springframework.messaging.Message<?> requestMessage) |
boolean |
isRunning() |
void |
setAppendNewLine(boolean appendNewLine)
If 'true' will append a new-line after each write.
|
void |
setAutoCreateDirectory(boolean autoCreateDirectory)
Specify whether to create the destination directory automatically if it
does not yet exist upon initialization.
|
void |
setBufferSize(int bufferSize)
Set the buffer size to use while writing to files; default 8192.
|
void |
setCharset(java.lang.String charset)
Set the charset name to use when writing a File from a String-based
Message payload.
|
void |
setChmod(int chmod)
Set the file permissions after uploading, e.g.
|
void |
setChmodOctal(java.lang.String chmod)
String setter for Spring XML convenience.
|
void |
setDeleteSourceFiles(boolean deleteSourceFiles)
Specify whether to delete source Files after writing to the destination
directory.
|
void |
setExpectReply(boolean expectReply)
Specify whether a reply Message is expected.
|
void |
setFileExistsMode(FileExistsMode fileExistsMode)
Will set the
FileExistsMode that specifies what will happen in
case the destination exists. |
void |
setFileNameGenerator(FileNameGenerator fileNameGenerator)
Provide the
FileNameGenerator strategy to use when generating
the destination file's name. |
void |
setFlushInterval(long flushInterval)
Set the frequency to flush buffers when
FileExistsMode.APPEND_NO_FLUSH is
being used. |
void |
setFlushPredicate(FileWritingMessageHandler.MessageFlushPredicate flushPredicate)
Set a
FileWritingMessageHandler.MessageFlushPredicate to use when flushing files when
FileExistsMode.APPEND_NO_FLUSH is being used. |
void |
setFlushWhenIdle(boolean flushWhenIdle)
Determine whether the
flushInterval applies only
to idle files (default) or whether to flush on that interval after the first
write to a previously flushed or new file. |
void |
setNewFileCallback(java.util.function.BiConsumer<java.io.File,org.springframework.messaging.Message<?>> newFileCallback)
Set the callback to use when creating new files.
|
protected void |
setPermissions(java.io.File resultFile)
Set permissions on newly written files.
|
void |
setPreserveTimestamp(boolean preserveTimestamp)
Set to true to preserve the destination file timestamp.
|
void |
setTemporaryFileSuffix(java.lang.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".
|
void |
start() |
void |
stop() |
void |
trigger(org.springframework.messaging.Message<?> message)
When using
FileExistsMode.APPEND_NO_FLUSH , you can send a message to this
method to flush any file(s) that needs it. |
doInvokeAdvisedRequestHandler, getRequiresReply, handleMessageInternal, hasAdviceChain, onInit, setAdviceChain, setBeanClassLoader, setRequiresReply
addNotPropagatedHeaders, createOutputMessage, getNotPropagatedHeaders, getOutputChannel, isAsync, produceOutput, resolveErrorChannel, sendErrorMessage, sendOutput, sendOutputs, setAsync, setNotPropagatedHeaders, setOutputChannel, setOutputChannelName, setSendTimeout, shouldCopyRequestHeaders, shouldSplitOutput, updateNotPropagatedHeaders
configureMetrics, destroy, getActiveCount, getActiveCountLong, getComponentType, getDuration, getErrorCount, getErrorCountLong, getHandleCount, getHandleCountLong, getManagedName, getManagedType, getMaxDuration, getMeanDuration, getMinDuration, getOrder, getOverrides, getStandardDeviationDuration, handleMessage, isCountsEnabled, isLoggingEnabled, isStatsEnabled, onComplete, onError, onNext, onSubscribe, registerMetricsCaptor, reset, setCountsEnabled, setLoggingEnabled, setManagedName, setManagedType, setOrder, setShouldTrack, setStatsEnabled
afterPropertiesSet, extractTypeIfPossible, generateId, getApplicationContext, getApplicationContextId, getBeanFactory, getBeanName, getChannelResolver, getComponentName, getConversionService, getExpression, getIntegrationProperties, getIntegrationProperty, getMessageBuilderFactory, getTaskScheduler, isInitialized, setApplicationContext, setBeanFactory, setBeanName, setChannelResolver, setComponentName, setConversionService, setMessageBuilderFactory, setPrimaryExpression, setTaskScheduler, toString
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
public FileWritingMessageHandler(java.io.File destinationDirectory)
destinationDirectoryExpression
using
a LiteralExpression
.destinationDirectory
- Must not be nullFileWritingMessageHandler(Expression)
public FileWritingMessageHandler(org.springframework.expression.Expression destinationDirectoryExpression)
destinationDirectoryExpression
.destinationDirectoryExpression
- Must not be nullFileWritingMessageHandler(File)
public void setAutoCreateDirectory(boolean autoCreateDirectory)
autoCreateDirectory
- true to create the directory if needed.public void setTemporaryFileSuffix(java.lang.String temporaryFileSuffix)
temporaryFileSuffix
- The temporary file suffix.public void setFileExistsMode(FileExistsMode fileExistsMode)
FileExistsMode
that specifies what will happen in
case the destination exists. For example FileExistsMode.APPEND
instructs this handler to append data to the existing file rather then
creating a new file for each Message
.
If set to FileExistsMode.APPEND
, the adapter will also
create a real instance of the LockRegistry
to ensure that there
is no collisions when multiple threads are writing to the same file.
Otherwise the LockRegistry is set to PassThruLockRegistry
which
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. For File
payloads,
the actual timestamp of the File
is compared; for other payloads,
the FileHeaders.SET_MODIFIED
is compared to the existing file.
If the header is missing, or its value is not a Number
, the file
is always replaced. This mode will typically only make sense if
preserveTimestamp
is true.
fileExistsMode
- Must not be nullsetPreserveTimestamp(boolean)
public void setExpectReply(boolean expectReply)
expectReply
- true if a reply is expected.public void setAppendNewLine(boolean appendNewLine)
appendNewLine
- true if a new-line should be written to the file after payload is writtenprotected java.lang.String getTemporaryFileSuffix()
public void setFileNameGenerator(FileNameGenerator fileNameGenerator)
FileNameGenerator
strategy to use when generating
the destination file's name.fileNameGenerator
- The file name generator.public void setDeleteSourceFiles(boolean deleteSourceFiles)
FileHeaders.ORIGINAL_FILE
header value containing either a
File instance or a String representing the original file path.deleteSourceFiles
- true to delete the source files.public void setCharset(java.lang.String charset)
charset
- The charset.public void setBufferSize(int bufferSize)
bufferSize
- the buffer size.public void setFlushInterval(long flushInterval)
FileExistsMode.APPEND_NO_FLUSH
is
being used. The interval is approximate; the actual interval will be between
flushInterval
and flushInterval * 1.33
with an average of
flushInterval * 1.167
.flushInterval
- the interval.setFlushWhenIdle(boolean)
public void setFlushWhenIdle(boolean flushWhenIdle)
flushInterval
applies only
to idle files (default) or whether to flush on that interval after the first
write to a previously flushed or new file.flushWhenIdle
- false to flush on the interval after the first write
to a closed file.setFlushInterval(long)
,
setBufferSize(int)
public void setFlushPredicate(FileWritingMessageHandler.MessageFlushPredicate flushPredicate)
FileWritingMessageHandler.MessageFlushPredicate
to use when flushing files when
FileExistsMode.APPEND_NO_FLUSH
is being used.
See trigger(Message)
.flushPredicate
- the predicate.public void setPreserveTimestamp(boolean preserveTimestamp)
File
, the payload's lastModified
time will be
transferred to the destination file. For other payloads, the
FileHeaders.SET_MODIFIED
header
will be used if present and it's a Number
.preserveTimestamp
- the preserveTimestamp to set.public void setChmodOctal(java.lang.String chmod)
chmod
- permissions as an octal string e.g "600";setChmod(int)
public void setChmod(int chmod)
chmod
- the permissions.java.lang.IllegalArgumentException
- if the value is higher than 0777.public void setNewFileCallback(java.util.function.BiConsumer<java.io.File,org.springframework.messaging.Message<?>> newFileCallback)
fileExistsMode
is FileExistsMode.APPEND
or FileExistsMode.APPEND_NO_FLUSH
and new file has to be created. The callback receives the new result file and the message that
triggered the handler.newFileCallback
- a BiConsumer
callback to be invoked when new file is created.protected void doInit()
doInit
in class org.springframework.integration.handler.AbstractReplyProducingMessageHandler
public void start()
start
in interface org.springframework.context.Lifecycle
public void stop()
stop
in interface org.springframework.context.Lifecycle
public boolean isRunning()
isRunning
in interface org.springframework.context.Lifecycle
protected java.lang.Object handleRequestMessage(org.springframework.messaging.Message<?> requestMessage)
handleRequestMessage
in class org.springframework.integration.handler.AbstractReplyProducingMessageHandler
protected void setPermissions(java.io.File resultFile) throws java.io.IOException
resultFile
- the file.java.io.IOException
- any exception.protected java.io.BufferedWriter createWriter(java.io.File fileToWriteTo, boolean append) throws java.io.FileNotFoundException
fileToWriteTo
- the file.append
- true if we are appending.java.io.FileNotFoundException
- if the file does not exist.protected java.io.BufferedOutputStream createOutputStream(java.io.File fileToWriteTo, boolean append) throws java.io.FileNotFoundException
fileToWriteTo
- the file.append
- true if we are appending.java.io.FileNotFoundException
- if not found.public void trigger(org.springframework.messaging.Message<?> message)
FileExistsMode.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 (String
or Pattern
) that matches the absolutePath
of any in-process files. However, if a custom FileWritingMessageHandler.MessageFlushPredicate
is provided,
the payload can be of any type supported by that implementation.trigger
in interface org.springframework.integration.handler.MessageTriggerAction
public void flushIfNeeded(FileWritingMessageHandler.FlushPredicate flushPredicate)
FileExistsMode.APPEND_NO_FLUSH
you can invoke this method to
selectively flush and close open files. For each open file the supplied
FileWritingMessageHandler.MessageFlushPredicate.shouldFlush(String, long, long, Message)
method is invoked and if true is returned, the file is flushed.flushPredicate
- the FileWritingMessageHandler.FlushPredicate
.public void flushIfNeeded(FileWritingMessageHandler.MessageFlushPredicate flushPredicate, org.springframework.messaging.Message<?> filterMessage)
FileExistsMode.APPEND_NO_FLUSH
you can invoke this method to
selectively flush and close open files. For each open file the supplied
FileWritingMessageHandler.MessageFlushPredicate.shouldFlush(String, long, long, Message)
method is invoked and if true is returned, the file is flushed.flushPredicate
- the FileWritingMessageHandler.MessageFlushPredicate
.filterMessage
- an optional message passed into the predicate.