Tomcat 9.0.59からデフォルトのCharsetとしてShift_JISが使用されるようになってしまいました
問題
Tomcat 9.0.59(spring boot 2.5.11/2.6.5)から、JP Local(accept-language: jp)のときにShift_JISが使われるようになりました。
その結果、次のような条件のときに文字化けする問題が発生しています。
resources/main/static
においている静的なHTMLがあるとき- ただし、"/hoge/index.html"のようにアクセスすれば問題なさそう。"/hoge/" でアクセスすると、問題がおきます。
- 拡張子があると、拡張子に応じてcontent-typeをspring側がよしなに変えているからだと思われる。深追いはしていません
- 自前で AbstractView を継承して実装しているケース (良い例を示すことが難しいですが)
普通にSpring BootのFreemarker / Thymeleafインテグレーションに沿って実装している場合は問題ありません。
Spring4Shell のためにSpring Bootのバージョンをあげると、この問題に遭遇する可能性があります。
原因
Tomcat 9.0.59にて、以下のcommitがされてしまいました。
https://github.com/apache/tomcat/commit/eda77...
TCKに以下の実装が追加されてしまったことにより、Tomcat側も追従したようです。
https://github.com/eclipse-ee4j/jakartaee-tck/commit/d6ee0...
対策
いくつか方法があります。
方法1
Spring Boot側で次のような対応がされました。そのため、今後リリースされるであろうSpring Bootのバージョンを使用すれば問題は解決します。
https://github.com/spring-projects/spring-boot/pull/30535
方法2
次のようなworkaroundをします。 (Spring Boot利用時のみ)
@Configuration(proxyBeanMethods = false)
class TomcatServletWebServerConfiguration {
@Bean
fun webServerFactoryCustomizer(): WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
return WebServerFactoryCustomizer<TomcatServletWebServerFactory> { factory ->
factory.mimeMappings = MimeMappings(MimeMappings.DEFAULT).also {
it.add("html", "text/html;charset=UTF-8")
}
}
}
}
方法3
tomcatのversionを明示的に9.0.58に下げる。
Tomcatへのフィードバック
以下のPRにて、Tomcat側にはフィードバックしています。
https://github.com/apache/tomcat/pull/493
もしかしたら今後Tomcat側でなにかしらの対応がされるかもしれません。