使用camel压缩和密码保护文件

时间:2014-10-15 23:23:25

标签: apache-camel

我一直在尝试在我的路线中压缩多个csv文件。我已经成功地做到了。

我使用spring做同样的事。

现在新要求是密码保护。以下是我使用的聚合策略。怎么做到这一点?

<route autoStartup="false" routePolicyRef="routeTwoTimer" startupOrder="2" id="zippingFileRoute">
    <from uri="{{to.file.processed1}}"/>
    <choice id="csvZipFile">
        <when>
            <simple>$simple{header.CamelFileName} regex '^.*(csv|CSV)$'</simple>
            <aggregate strategyRef="zipAggregationStrategy" completionFromBatchConsumer="true" eagerCheckCompletion="true">
                <correlationExpression>
                    <constant>true</constant>
                </correlationExpression>
                <to uri="{{to.file.processed2}}"/>
            </aggregate>
        </when>
    </choice>
</route>

1 个答案:

答案 0 :(得分:0)

正如评论中所指出的,Java API在加密ZIP文件方面有点受限。 Apache Camel ZipAggregationStrategy正在使用ZipOutputStream,所以也有这个限制。您可以使用任何其他库来实现自定义Aggregator,这允许加密Zip文件。例如Zip4j

添加Maven依赖

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>1.3.2</version>
</dependency>

实施自定义聚合器

import net.lingala.zip4j.core.ZipFile;
//next few imports. I have added this only to take correct ZipFile class, not the JDK one 

public class PasswordZipAggregationStrategy implements AggregationStrategy {

public static final String ZIP_PASSWORD_HEADER = "PasswordZipAggregationStrategy.ZipPassword";

@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange){
    try {
        if (newExchange == null) {
            return oldExchange;
        }
        return aggregateUnchecked(oldExchange,newExchange);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private Exchange aggregateUnchecked(Exchange oldExchange, Exchange newExchange) throws Exception{
    ZipFile zipFile;
    String password;
    if (oldExchange == null) { // first
        password = newExchange.getIn().getHeader(ZIP_PASSWORD_HEADER, String.class);
        zipFile = new ZipFile(newExchange.getExchangeId()+".zip");
        File toDelete = new File(zipFile.getFile().getPath());
        newExchange.addOnCompletion(new Synchronization() {
            @Override
            public void onComplete(Exchange exchange) {
                toDelete.delete();
            }

            @Override
            public void onFailure(Exchange exchange) {
            }
        });
    } else {
        password = newExchange.getIn().getHeader(ZIP_PASSWORD_HEADER, String.class);
        zipFile = new ZipFile(oldExchange.getIn().getBody(File.class));
    }

    if (password==null){
        throw new IllegalStateException("Null password given");
    }

    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setPassword(password);
    zipParameters.setEncryptFiles(true);
    zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_FAST);
    zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
    zipFile.addFile(newExchange.getIn().getBody(File.class), zipParameters);
    GenericFile genericFile = FileConsumer.asGenericFile(zipFile.getFile().getParent(), zipFile.getFile(), Charset.defaultCharset().toString(), false);
    genericFile.bindToExchange(newExchange);

    newExchange.getIn().setBody(zipFile.getFile());
    newExchange.getIn().setHeader(ZIP_PASSWORD_HEADER, password);
    return newExchange;
}
}

使用

from("file://in")
    .to("log:in")
    .setHeader(PasswordZipAggregationStrategy.ZIP_PASSWORD_HEADER, constant("testPassword"))
    .aggregate().constant(true).completionFromBatchConsumer()
        .aggregationStrategy(new PasswordZipAggregationStrategy())
.to("log:out")
.to("file://out");