spring+camel+FTP モジュールがあります。FTP サーバーからファイルをダウンロードし、ZipInputStream を使用して zip ファイルからデータを抽出する必要があります。ここに私の追加のクラスがあります:
public class TransactionsSupport {
protected final Logger l = LoggerFactory.getLogger(getClass());
protected void copy(InputStream is, OutputStream os, byte[] buffer) throws IOException {
int len;
while ((len = is.read(buffer)) >= 0) {
os.write(buffer, 0, len);
}
is.close();
os.close();
}
public void copy(InputStream is, OutputStream os) throws IOException {
copy(is, os, new byte[4096]);
}
public byte[] unzip(ZipInputStream zipInputStream) {
byte[] bytes = null;
try {
ZipEntry entry = zipInputStream.getNextEntry();
l.info("{}", entry.getName());
ByteArrayOutputStream streamBuilder = new ByteArrayOutputStream();
copy(zipInputStream, streamBuilder);
bytes = streamBuilder.toByteArray();
l.info("bytes.length {}", bytes.length);
} catch (IOException ex) {
l.error(ex.getMessage(), ex);
} finally {
if (zipInputStream != null) {
try {
zipInputStream.close();
} catch (IOException ex) {
l.error(ex.getMessage(), ex);
}
}
}
return bytes;
}
このコードをローカル ファイルで正常にテストしました。
public void inputStream2OutputStream(InputStream stream, OutputStream out) throws IOException {
int readedBytes;
byte[] buf = new byte[1024];
while ((readedBytes = stream.read(buf)) > 0) {
out.write(buf, 0, readedBytes);
}
stream.close();
out.close();
}
@Test
public void fromByteArrayStreamToZipInputStreamTest() throws IOException, UnsupportedTransactionType, WrongRecordsNumberException, WrongCheckSum {
File fileIn = new File((postedTransactionPath + postedTransactionFileName));
FileInputStream in = new FileInputStream(fileIn);
ByteArrayOutputStream out = new ByteArrayOutputStream();
inputStream2OutputStream(in, out);
InputStream inS = new ByteArrayInputStream(out.toByteArray());
ZipInputStream s = new ZipInputStream(inS);
byte[] bytes = support.unzip(s);
inS.close();
s.close();
String text = new String(bytes);
l.info(text);
parser.parse(text);
// 大丈夫です }
しかし、キャメル経由で処理しようとすると、「ZLIB 入力ストリームの予期しない終了」が発生しました。私のプロセッサは次のとおりです。
@Override
public void process(Exchange exchange) throws Exception {
l.info(exchange);
RemoteFile remoteFile = (RemoteFile) exchange.getIn().getBody();
ByteArrayOutputStream streamOut = (ByteArrayOutputStream) remoteFile.getBinding().getBody(new GenericFile());
ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(streamOut.toByteArray()));
l.info("file name: {}" + remoteFile.getFileName());
TransactionsSupport support = new TransactionsSupport();
byte[] bytes = support.unzip(zipStream); //Here we have exception that is refferenced to method copy() of TransactionsSupport class
String text = new String(bytes);
l.info(text);
parser.parse(text);
if (((FirstDataTransactionsParser) parser).getHeader() == null) {
l.error("ERRORRRRR");
}
入力ストリームが処理される前に、キャメルまたはスプリングが入力ストリームを閉じると思います。では、このような動作を防ぐにはどうすればよいでしょうか。また、ストリームを手動で閉じたい場合はどうすればよいでしょうか。
ここに私のルートがあります:
<routeContext id="transactionsRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="routeFTP">
<from uri="direct:start" />
<from uri="ftps://{{ftps.host}}:2190/"/>
<to uri="file://target/test-reports1234/"/>
<doTry>
<bean ref="transactionsProcessor"/>
<doCatch>
<exception>java.lang.Exception</exception>
<bean ref="exceptionProcessor"/>
</doCatch>
<doFinally>
<bean ref="responsePublisher"/>
</doFinally>
</doTry>
</route>
</routeContext>
<camelContext id="com.nxsystems.camel" xmlns="http://camel.apache.org/schema/spring" trace="true">
<routeContextRef ref="transactionsRoutes"/>
</camelContext>