InputStream を RESTful サービスに投稿しようとしています。通常のファイルの場合、これで問題ありません。
別の場所では、多数のファイルをその場でパイプされた zip ストリームに書き込もうとしています。これを行うには、拡張するクラスがInputStream
あり、呼び出されたときread()
に次のファイルをパイプに書き込みます。最初のファイルが書き込まれたときに呼び出しますZipOutputStream.closeEntry()
が、ハングします。どうして??
このクラスを単体テストでテストすると、正常に動作します。このオブジェクトを投稿しようとすると、ハングします。デバッガーは、ロックオンを待っていると言っていますSocketWrapper
。
メディアタイプを に設定しようとしたことにも注意してくださいapplication/octet-stream
。また、RESTful メソッドが呼び出されることはありません。
ストリームクラス...
static class MultiStreamZipInputStream extends InputStream {
private final Iterator<InputStream> streams;
private final byte[] buffer = new byte[4096];
private InputStream inputStream;
private ZipOutputStream zipOutputStream;
private InputStream currentStream;
private int counter = 0;
public MultiStreamZipInputStream(List<InputStream> streamList) {
streams = streamList.iterator();
currentStream = streams.next();
try {
PipedOutputStream out = new PipedOutputStream();
inputStream = new PipedInputStream(out);
zipOutputStream = new ZipOutputStream(out);
ZipEntry entry = new ZipEntry(String.valueOf(counter++)); // Use counter for random name
zipOutputStream.putNextEntry(entry);
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public int read()
throws IOException {
if (inputStream.available() != 0)
return inputStream.read();
if (currentStream == null)
return -1;
int bytesRead = currentStream.read(buffer);
if (bytesRead >= 0) {
zipOutputStream.write(buffer, 0, bytesRead);
zipOutputStream.flush();
} else {
currentStream.close();
zipOutputStream.closeEntry();
if (!streams.hasNext()) {
currentStream = null;
return -1;
}
currentStream = streams.next();
zipOutputStream.putNextEntry(new ZipEntry(String.valueOf(counter++)));
}
return read();
}
}
投稿コードは...
MultiStreamZipInputStream myStream = ...
Client client = Client.create();
Builder webResource = client.resource("some URL").type("application/x-zip-compressed");
webResource.post(ClientResponse.class, myStream);
もう一方の REST メソッドは...
@POST
@Path("/somemethod")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({"application/x-zip-compressed"})
public Response someMethod(InputStream data) {...