概要
Dispatchを使ってHTTPクライアントを作ると、稀に文字化けすることがあるので、その原因と対策をまとめる。
ちなみにDispatchはAsyncHttpClientを内部で使っていて、今回の話題はAsyncHttpClientの領域にも少し踏み込む。
原因と解決方針
文字化けの原因はHTTPクライアントにはよくある話で、HTTPレスポンスヘッダのContent-Typeにcharsetがセットされていない(または間違っている)のが原因。
Bodyバイト列をStringに変換するときにContent-Typeのcharsetを用いるのだが、デフォルトではISO-8859-1が使われるため、charset未設定のヘッダが来ると、bodyの文字コードが例えUTF8であっても化けてしまう。
で、これの解決方法として、ResponseFilterを使う。
ResponseFilterはAsyncHttpClient側の機能で、bodyの解析前に処理を挟むことができる。これを用いて、ヘッダのContent-Typeにcharsetを書き込んでしまえば良い。
DispatchからResponseFilterを挟む
あとは実際にコードを書くだけだが、今回はDispatchからの利用なのでDispatchのAPIからResponseFilterを挟む必要がある。実際にコードを見たほうが早いだろう。
Dispatchで提供されるデフォルトのHttpはconfigureメソッドを持っており、これにAsyncHttpClientConfig.Builderをいじる関数を渡してやることで、HTTPクライアントの挙動を制御することができる。今回はaddResponseFilterを使ってResponseFilterを挟んでやろうと言うわけだ。ResponseFilterの実装はcharset無しのContent-Typeが渡ってきたらcharset付きで上書きしてやろうというもの。Scalaの感覚で「Filter」というとFilterContextを受け取って新しいFilterContextを生成する実装をしたくなるが、ここでは単純にmutableなオブジェクトの操作でOK。
この例では"text/html"の時だけUTF-8を指定しているだけだが、必要に応じて実装を書き換えてやれば良い。
参考
Http.configureについてはこちら、AsyncHttpClientConfig.Builderについてはこちら、ResponseFilterについてはこちらを参照。
0 件のコメント:
コメントを投稿