HttpClientがGZIP形式でない場合の対処法
HttpClientで画像を取得する過程で、以下のようなエラーが表示されました。
Exception in thread "main" java.util.zip.ZipException: Not in GZIP format
GZIPInputStream.readHeader(GZIPInputStream.java:165)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:91)
at org.apache.http.client.protocol.ResponseContentEncoding$1.create(ResponseContentEncoding.java:68)
at org.apache.http.client.entity.LazyDecompressingInputStream.initWrapper(LazyDecompressingInputStream.java:51)
at org.apache.http.client.entity.LazyDecompressingInputStream.read(LazyDecompressingInputStream.java:63)
at com.didichuxing.upload.TestUploadFile.main(TestUploadFile.java:53)
例外スタックのソースコードを読むと、HTTPリクエストヘッダに "Content-Encoding: "compress,gzip"" が含まれており、これを元にHttpClientが返ってきたInputStreamを "Content-Encoding" に従ってラップしており、そのソースコードは以下の通りであることがわかりました。
// excerpt, see org.apache.http.client.protocol.ResponseContentEncoding for details
final Header ceheader = entity.getContentEncoding();
// ......
// with ignore
final InputStreamFactory decoderFactory = decoderRegistry.lookup(codecname);
つまり、2つの関連するソリューションがあるわけです。
1.クライアント側の解決策
HTTPリクエストを診断するには、ヘッダー情報がポイントになります。
"Content-Encoding", "compress,gzip"
しかし残念ながら、クライアントにはHTTPヘッダを変更する機能はありません( 読み取りアクセスのみ ) のため、HttpClientがGZIPで処理する前に、以下のようにしてストリームを取得する必要があります。
CloseableHttpClient httpclient = HttpClients.custom().addInterceptorFirst(new HttpResponseInterceptor() {
@Override
public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
HttpEntity resEntity = response.getEntity();
// consume the InputStream here
BufferedInputStream ins = new BufferedInputStream(resEntity.getContent());
FileOutputStream fos = new FileOutputStream("water1.png");
byte[] buffer = new byte[4096];
int len = 0;
while((len = ins.read(buffer)) > -1) {
fos.write(buffer, 0, len);
}
fos.close();
}
}).build();
要約すると、このエラーの根本原因のほとんどは、以下のようにHttpClientのデフォルトの構成に起因しています。
// Generic role, but not applicable in all cases
CloseableHttpClient httpclient = HttpClients.createDefault();
2. サーバーサイドソリューション
サーバーサイドでの解決方法は簡単ですが、唯一の問題は、コードを修正するために、以下のようにサーバーサイドのアクセス権が必要なことです。
// Don't enable this mode
// response.setHeader("Content-Encoding", "compress,gzip");
// change to normal stream mode
response.setHeader("Content-Encoding", "application/octet-stream");
ふと、冗談が頭に浮かぶ。
<ブロッククオート専門家は、中国の神爆がいかに強力か、米帝のホワイトハウスの上を軍用機が飛ぶだけで、白地に吹き飛ぶと自慢しているのだ。そこで問題なのは、軍用機がどうやってどこに行くのか、ということだ。
もうひとつの方法は、サーバー側で実際にGZipモードをサポートすることです。 GZIP圧縮を有効にするためのTOMCATのセットアップ [私は何度かこれを試しましたが、特に画像サポートではうまくいかないようです]。
3. その他
JAVA HttpClientを使用したファイルの自動アップロード、クロールの詳細は以下の通りです。
1.
ファイルアップロードのためのHTTPクライアントアプローチ
2.
HTTPクライアントからファイルをアップロードするための改良されたアプローチ
4. 参考文献
関連
-
Java Error スレッド "AWT-EventQueue-0" で例外発生 java.lang.
-
プロジェクトの依存関係を解決できなかった 解決
-
サーブレットクラスのインスタンス化エラーの解決法
-
VMの初期化中にエラーが発生しました java/lang/NoClassDefFoundError: java/lang/Object
-
テストが見つかりませんでした
-
ローカルリソースのロードが許可されていない場合の解決策
-
Maven Pluginの実行がライフサイクル設定の対象外であるエラーの解決
-
Ali cloud ubuntu16 システムで LAMP を構築し、tomcat、jdk をインストールし、最初の javaweb プロジェクトを tomcat にデプロイする 詳細手順
-
Swagger の @ApiModelProperty オブジェクト フィールドが表示されない
-
引数型[java.lang.String]の名前がありません..........................。.バグ処理
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java Exceptionが発生しました エラー解決
-
java の例外が発生しました java
-
myeclipseでコンパイルするとAntエラーが発生する javaの例外が発生しました。
-
eclipse アクセス制限です。タイプ 'xxx' は API ではありません(必須ライブラリ '' の制限)。
-
this()の呼び出しはコンストラクタ本体の最初の文でなければならない 例外解決と原因分析
-
spring-boot 401 このリソースにアクセスするには完全な認証が必要です エラー解決
-
SocketTimeoutExceptionです。読み込みがタイムアウトしました
-
あるコードに出会いましたが、何に使うのか理解できません。 List<String> list = new ArrayList<String>() { { a
-
java 例外。Javaツールの初期化
-
Javaドッキングリーダの落とし穴について終了コード -1073740940 (0xC0000374)でプロセス終了