最後に、私の最終的な目標は次のとおりです。
- URL から読み取る (この質問の内容)
- 取得した [PDF] コンテンツを DB の BLOB フィールドに保存します (既に特定されています)。
- BLOB フィールドから読み取り、そのコンテンツをメールに添付します
- ファイルシステムにアクセスする必要はありません
次のメソッドの目的はbyte[]
、電子メールの添付ファイルとしてダウンストリームで使用できる を取得することです (ディスクへの書き込みを避けるため)。
public byte[] retrievePDF() {
HttpClient httpClient = new HttpClient();
GetMethod httpGet = new GetMethod("http://website/document.pdf");
httpClient.executeMethod(httpGet);
InputStream is = httpGet.getResponseBodyAsStream();
byte[] byteArray = new byte[(int) httpGet.getResponseContentLength()];
is.read(byteArray, 0, byteArray.length);
return byteArray;
}
特定の PDF の場合、このgetResponseContentLength()
メソッドは長さとして 101,689 を返します。奇妙な点は、ブレークポイントを設定してbyteArray
変数に問い合わせると、101,689 バイトの要素があるのに、バイト #3744 の後、配列の残りのバイトがすべてゼロ ( 0
) になることです。 結果の PDF は、Adobe Reader などの PDF リーダー クライアントでは読み取ることができません。
なぜそれが起こるのでしょうか?
この同じ PDF をブラウザー経由で取得してディスクに保存するか、次のような方法 (この StackOverflow 投稿への回答に基づいてパターン化したもの) を使用すると、読み取り可能な PDF が生成されます。
public void retrievePDF() {
FileOutputStream fos = null;
URL url;
ReadableByteChannel rbc = null;
url = new URL("http://website/document.pdf");
DataSource urlDataSource = new URLDataSource(url);
/* Open a connection, then set appropriate time-out values */
URLConnection conn = url.openConnection();
conn.setConnectTimeout(120000);
conn.setReadTimeout(120000);
rbc = Channels.newChannel(conn.getInputStream());
String filePath = "C:\\temp\\";
String fileName = "testing1234.pdf";
String tempFileName = filePath + fileName;
fos = new FileOutputStream(tempFileName);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
fos.flush();
/* Clean-up everything */
fos.close();
rbc.close();
}
どちらのアプローチでも、Windows で右クリック > プロパティ...を実行すると、結果の PDF のサイズは 101,689 バイトになります。
バイト配列が本質的に途中で「停止」するのはなぜですか?