Reputation: 17
I'm developing a spring batch to read multiple files from a folder, process it and write the result in DB. I'm using MultiResourceItemReader to read files from the folder. but the files might be encrypted so , i need to decrypt the file before reading. What is the best way to do this?
1) Should I use a step before reading, processing and writing ? 2) Should I override doOpen from FlatFileItemReader which was set as delegate to MultiResourceItemReader ? 3) Should I override open in MultiResourceItemReader itself ?
I think, overriding an already existing method is not advisable, as we may end up in duplication or missing code. Please advise
Upvotes: 0
Views: 738
Reputation: 6630
I guess you are using a FlatFileItemReader as delegate here?
Then you could make it with a customized BufferedReaderFactory
Java Code (not tested! i have no experience using Cipher)
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.springframework.batch.item.file.BufferedReaderFactory;
import org.springframework.core.io.Resource;
public class EncryptedBufferedItemReaderFactory implements BufferedReaderFactory {
private String keyFile;
private String algorithm;
@Override
public BufferedReader create(final Resource resource, final String encoding) throws UnsupportedEncodingException, IOException {
FileInputStream fis = new FileInputStream(resource.getFile());
CipherInputStream cis = new CipherInputStream(fis, createCipher());
return new BufferedReader(new InputStreamReader(cis, encoding));
}
private Cipher createCipher() throws IOException, FileNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(keyFile));
Cipher cipher;
try {
DESKeySpec ks = new DESKeySpec((byte[]) ois.readObject());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey key = skf.generateSecret(ks);
cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec((byte[]) ois.readObject()));
} catch (Exception ex) {
throw new IOException(ex);
} finally {
ois.close();
}
return cipher;
}
public void setKeyFile(final String keyFile) {
this.keyFile = keyFile;
}
public void setAlgorithm(final String algorithm) {
this.algorithm = algorithm;
}
}
for algorithm see Java standard algorithms
example bean configuration
<bean id="multiResourceItemReader" class="org.springframework.batch.item.file.MultiResourceItemReader" scope="step">
<property name="resources" value="#{jobParameters['whateverYouChosen']}" />
<property name="delegate" ref="flatFileItemReader" />
</bean>
<bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<!-- some properties you already have, like lineMapper -->
<property name="bufferedReaderFactory" ref ="encryptedBufferedReaderFactory" />
</bean>
<bean id="encryptedBufferedReaderFactory" class="your.com.package.EncryptedBufferedReaderFactory" scope="step">
<property name="keyFile" value="#{jobParameters['pathToKeyFile']}" />
<property name="algorithm" value="#{jobParameters['algorithm']}" />
</bean>
Upvotes: 0