Zip Support
This Spring Integration module provides Zip (un-)compression support. A zipping algorithm implementation is based on a ZeroTurnaround ZIP Library. The following components are provided:
You need to include this dependency into your project:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-zip</artifactId>
<version>6.4.0</version>
</dependency>
compile "org.springframework.integration:spring-integration-zip:6.4.0"
Namespace Support
All components within the Spring Integration Zip module provide namespace support. In order to enable namespace support, you need to import the schema for the Spring Integration Zip Module. The following example shows a typical setup:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-zip="http://www.springframework.org/schema/integration/zip"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/zip
https://www.springframework.org/schema/integration/zip/spring-integration-zip.xsd">
</beans>
(Un)Zip Transformer
The ZipTransformer
implements a zipping functionality for these types of input payload
: File
, String
, byte[]
and Iterable
.
In input data types can be mixed as part of an Iterable
.
For example, it should be easily to compress a collection containing Strings, byte arrays and Files.
It is important to note that nested Iterables are NOT SUPPORTED at present time.
The ZipTransformer
can be customized by setting several properties:
-
compressionLevel
- sets the compression level. Default isDeflater#DEFAULT_COMPRESSION
. -
useFileAttributes
- specifies whether the name of the file shall be used for the zip entry. -
fileNameGenerator
- uses to generate an original file name based on the request message. Defaults toDefaultFileNameGenerator
. The.zip
extension is added into this name for the target zip file name. Unless it is already present as a result of this generator.
In addition, a ZipHeaders.ZIP_ENTRY_FILE_NAME
and ZipHeaders.ZIP_ENTRY_LAST_MODIFIED_DATE
can be supplied for the name of zip entry and its lastmodified
attribute.
If not provided, the entry name is exact result of the fileNameGenerator
and lastmodified
falls back to the current date and time.
If the payload of request message is an Iterable
, then this entry name is modified with an index starting 1
.
For example to zip a simple test.txt
file into a test.txt.zip
, only this configuration is enough:
-
Java DSL
-
Kotlin DSL
-
Groovy DSL
-
Java
-
XML
@Bean
public IntegrationFlow zipFlow() {
return IntegrationFlow
.from("zipChannel")
.transform(new ZipTransformer())
.get();
}
@Bean
fun zipFlow() =
integrationFlow("zipChannel") {
transform(ZipTransformer())
}
@Bean
zipFlow() {
integrationFlow 'zipChannel',
{
transform new ZipTransformer()
}
}
@Transformer(inputChannel = "zipChannel")
@Bean
ZipTransformer zipTransformer() {
return new ZipTransformer();
}
<int-zip:zip-transformer input-channel="zipChannel"/>
See ZipTransformer
Javadocs for more information.
An UnZipTransformer
supports these of input payload
: File
, byte[]
and InputStream
.
When unzipping data, an expectSingleResult
property can be specified.
If set to true
and more than 1
zip entry were detected, a MessagingException
will be raised.
This property also influences the return type of the payload.
If set to false
(default), then the payload will be of type SortedMap
, if true
, however, the actual zip entry will be returned.
Other properties that can be set on the UnZipTransformer
:
-
deleteFiles
- if the payload is an instance ofFile
, this property specifies whether to delete the File after transformation. Default isfalse
. -
ZipResultType
- defines the format of the data returned after transformation. Available options are:File
,byte[]
. -
workDirectory
- the work directory is used when aZipResultType
is set toZipResultType.FILE
. By default, this property is set to the System temporary directory containing a subdirectoryziptransformer
.
For example to zip a simple test.zip
file into a map of its entries, only this configuration is enough:
-
Java DSL
-
Kotlin DSL
-
Groovy DSL
-
Java
-
XML
@Bean
public IntegrationFlow unzipFlow() {
return IntegrationFlow
.from("unzipChannel")
.transform(new UnZipTransformer())
.get();
}
@Bean
fun unzipFlow() =
integrationFlow("unzipChannel") {
transform(UnZipTransformer())
}
@Bean
unzipFlow() {
integrationFlow 'unzipChannel',
{
transform new UnZipTransformer()
}
}
@Transformer(inputChannel = "unzipChannel")
@Bean
UnZipTransformer unzipTransformer() {
return new UnZipTransformer();
}
<int-zip:unzip-transformer input-channel="unzipChannel"/>
Unzipped Splitter
The UnZipResultSplitter
is useful in cases where zip files contain more than 1
entry.
Essentially it has to be used as the next step in the integration flow after the mentioned above UnZipTransformer
.
It supports only a Map
as an input data and emits every entry into an outputChannel
with FileHeaders.FILENAME
and ZipHeaders.ZIP_ENTRY_PATH
headers.
The following example demonstrates a simple configuration for splitting unzipped result:
-
Java DSL
-
Kotlin DSL
-
Groovy DSL
-
Java
-
XML
@Bean
public IntegrationFlow unzipSplitFlow(Executor executor) {
return IntegrationFlow
.from("unzipChannel")
.transform(new UnZipTransformer())
.split(new UnZipResultSplitter())
.channel(c -> c.executor("entriesChannel", executor))
.get();
}
@Bean
fun unzipFlow(executor: Executor) =
integrationFlow("unzipChannel") {
transform(UnZipTransformer())
split(UnZipResultSplitter())
channel { executor("entriesChannel", executor) }
}
@Bean
unzipFlow(Executor executor) {
integrationFlow 'unzipChannel',
{
transformWith {
ref new UnZipTransformer()
}
splitWith {
ref new UnZipResultSplitter()
}
channel { executor 'entriesChannel', executor }
}
}
@Transformer(inputChannel = "unzipChannel", outputChannel = "splitChannel")
@Bean
UnZipTransformer unzipTransformer() {
return new UnZipTransformer();
}
@Spitter(inputChannel = "splitChannel", outputChannel = "entriesChannel")
@Bean
UnZipResultSplitter unZipSplitter() {
return new UnZipResultSplitter();
}
@Bean
ExecutorChannel entriesChannel(Executor executor) {
return new ExecutorChannel(executor);
}
<int:chain input-channel="unzipChannel" output-channel="entriesChannel">
<int-zip:unzip-transformer/>
<int:splitter>
<bean class="org.springframework.integration.zip.splitter.UnZipResultSplitter"/>
</int:splitter>
</int:chain>
<int:channel id="entriesChannel">
<int:dispatcher task-executor="executor"/>
</int:channel>