SpringBoot(Thymeleaf)でレスポンスの文字コードを指定する
通常であればアプリケーションで使用する文字コードは 1 つだと思います。
今の時代なら「UTF-8」でしょうし、古いサイトであれば「EUC-JP」や「Shift_JIS」もまだまだ現役です。
しかし外部との連携が増えてきた昨今、相手側のサイトの都合上、レスポンスで返す JSON や HTML の文字コードを切り替えないといけない場面も出てきます。
今回は、Kotlin と Spring Boot を組み合わせたサーバサイドアプリで、レスポンスの文字コードを変更する方法を紹介します。
レスポンスヘッダの設定変更
レスポンスの文字コードを変更する場合、真っ先に思いつくのはレスポンスヘッダの指定です。
使用する言語によって、Content-Type と合わせて Charset を上書きする方法や Charset だけを指定する方法があります。
Kotlin や Java の場合は、HttpServletResponse を使って以下のように設定できます。
// 両方設定
response.setHeader("Content-Type", "text/html; charset=utf-8")
// Content-Typeのみ
response.setContentType("text/html")
// 文字コードのみ
response.setCharacterEncoding("utf-8")
PHP だとレスポンスの最後に以下を指定するだけですね。
header("Content-type: text/html; charset=utf-8");
コンテンツと文字コード個別で指定できない場合
しかし、Kotlin と Spring Boot のバージョンによっては以下のメソッドが使用できないことがあります。
要は引数に String 型が指定できないパターンですね。
// Content-Typeのみ
response.setContentType("text/html");
// 文字コードのみ
response.setCharacterEncoding("utf-8");
これについては詳しく調べ切れていないので今回は触れません。
Thymeleafをビューに使う場合
また、ビューにテンプレートエンジンの Thymeleaf を使う場合は HttpServletResponse の設定が反映されません。
response.setHeader("Content-Type", "text/html; charset=utf-8")
return "index"
response.getWriter().write(“コンテンツ”) でコンテンツを出力する場合は問題ないですが、Thymeleaf のテンプレートで出力する場合はまた別の設定が使われることになります。
そこで、Spring Boot の @RequestMapping や @PostMapping などのアノテーションで produces を指定します。
これにより、Content-Type を設定することができます。例えば、特定のリクエストだけレスポンスを Shift_JIS にしたい場合は以下のように @PostMapping や @GetMapping 単位で指定します。
@PostMapping("/index", produces = ["text/html; charset=Shift_JIS"])
@GetMapping("/index", produces = ["text/html; charset=Shift_JIS"])
コントローラ全体で指定する場合は、@RequestMapping の produces に設定すれば問題ありません。
nkfによるhtmlファイルの文字コード確認
ちなみに、出力時の文字コードを「Shift_JIS」にする場合、Thymeleaf の html ファイルの文字コードは UTF-8 のままで問題ありません。
文字コードの確認は IDE やテキストエディタでもいいですが、ターミナル上で確認する場合は nkf が楽です。
$ nkf -g index.html
Shift_JIS
ファイルの文字コードを変更したい場合は、文字コードを指定して上書きをします。
# UTF-8にする
$ nkf -w --overwrite index.html
# Shift_JISにする
$ nkf -s --overwrite index.html
Eclipse や IntelliJ IDEA などの IDE で Thymeleaf の html ファイルを保存した際に、文字コードが自動で書き換えられてしまった場合などに確認してみてください。