コンテンツにスキップ

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側でなにかしらの対応がされるかもしれません。


最終更新日: 2022/04/14 03:48