问题描述:

When using a directory-expression for an <int-file:outbound-gateway> endpoint, the method below is called on org.springframework.integration.file.FileWritingMessageHandler:

private File evaluateDestinationDirectoryExpression(Message<?> message) {

final File destinationDirectory;

final Object destinationDirectoryToUse = this.destinationDirectoryExpression.getValue(

this.evaluationContext, message);

if (destinationDirectoryToUse == null) {

throw new IllegalStateException(String.format("The provided " +

"destinationDirectoryExpression (%s) must not resolve to null.",

this.destinationDirectoryExpression.getExpressionString()));

}

else if (destinationDirectoryToUse instanceof String) {

final String destinationDirectoryPath = (String) destinationDirectoryToUse;

Assert.hasText(destinationDirectoryPath, String.format(

"Unable to resolve destination directory name for the provided Expression '%s'.",

this.destinationDirectoryExpression.getExpressionString()));

destinationDirectory = new File(destinationDirectoryPath);

}

else if (destinationDirectoryToUse instanceof File) {

destinationDirectory = (File) destinationDirectoryToUse;

} else {

throw new IllegalStateException(String.format("The provided " +

"destinationDirectoryExpression (%s) must be of type " +

"java.io.File or be a String.", this.destinationDirectoryExpression.getExpressionString()));

}

validateDestinationDirectory(destinationDirectory, this.autoCreateDirectory);

return destinationDirectory;

}

Based on this code I see that if the directory to use evaluates to a String, it uses that String to create a new java.io.File object.

Is there a reason that a ResourceLoader couldn't/shouldn't be used instead of directly creating a new file?

I ask because my expression was evaluating to a String of the form 'file://path/to/file/' which of course is an invalid path for the java.io.File(String) constructor. I had assumed that Spring would treat the String the same way as it treats the directory attribute on <int-file:outbound-gateway> and pass it through a ResourceLoader.

Excerpt from my configuration file:

<int-file:outbound-gateway

request-channel="inputChannel"

reply-channel="updateTable"

directory-expression="

'${baseDirectory}'

+

T(java.text.MessageFormat).format('${dynamicPathPattern}', headers['Id'])

"

filename-generator-expression="headers.filename"

delete-source-files="true"/>

Where baseDirectory is a property that changes per-environment of the form 'file://hostname/some/path/'

网友答案:

There's no particular reason that this is the case, it probably just wasn't considered at the time of implementation.

The request sounds reasonable to me and will benefit others (even though you have found a work-around), by providing simpler syntax. Please open an 'Improvement' JIRA issue; thanks.

网友答案:

While not directly answering the question, I wanted to post the workaround that I used.

In my XML configuration, I changed the directory-expression to evaluate to a file through the DefaultResourceLoader instead of a String.

So this is what my new configuration looked like:

<int-file:outbound-gateway 
    request-channel="inputChannel"
    reply-channel="updateTable"
    directory-expression=" new org.springframework.core.io.DefaultResourceLoader().getResource(
        '${baseDirectory}'
        +
        T(java.text.MessageFormat).format('${dynamicPathPattern}', headers['Id'])).getFile()
    "
    filename-generator-expression="headers.filename"
    delete-source-files="true"/>
相关阅读:
Top