Spring Boot: Request method ‘POST’ not supported

2年前のWEB+DB PRESS Vol.109 特集2 実践 Kotlinのサンプルコードを写経していました。

当時の動作環境は、
Kotlin 1.3.20
Thymeleaf
Spring Boot 2.1.2

削除ボタンのHTMLテンプレートは、

<form th:object="${task}" th:action="@{/task/{id}(id=${task.id})}" th:method="delete"> <button class="btn btn-outline-danger btn-sm" type="submit"> X </button> </form>
Code language: HTML, XML (xml)

ブラウザに表示されたHTMLソースは、

<form action="/task/8" method="post"><input type="hidden" name="_method" value="delete"/> <button class="btn btn-outline-danger btn-sm" type="submit"> X </button> </form>
Code language: HTML, XML (xml)

コントローラのdeleteメソッドは、

@DeleteMapping("{id}") fun delete( attributes: RedirectAttributes, @PathVariable id: Long ): String { taskRepository.deleteById(id) attributes.addFlashAttribute( "success", "タスクを削除しました。" ) return "redirect:/task" }
Code language: Kotlin (kotlin)

ところが、ブラウザで削除ボタンをクリックすると、405エラー

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Sat May 15 00:24:17 JST 2021 There was an unexpected error (type=Method Not Allowed, status=405).
Code language: plaintext (plaintext)

ターミナルのログにもエラーが表示されていました。

2021-05-15 00:44:46.226 WARN 11443 --- [io-12345-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
Code language: plaintext (plaintext)

いくつかの記事をたどっていくと、Spring Boot 2.2で、_method用フィルターがデフォルトで無効になり、それが原因のようです。

HttpHiddenMethodFilter disabled by default

The filter that handles the _method request parameter is now disabled by default as it causes early consumption of a request body if the body may contain parameters. This can be restored by setting either spring.webflux.hiddenmethod.filter.enabled or spring.mvc.hiddenmethod.filter.enabled to true.

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes#httphiddenmethodfilter-disabled-by-default

現在のSprint Bootバージョンは、2.4.5 でした。

有効にするには、myapp/src/main/resources/application.properties に、

spring.mvc.hiddenmethod.filter.enabled=true spring.webflux.hiddenmethod.filter.enabled=true
Code language: plaintext (plaintext)

を記述します。

ターミナルでコントロールCでサーバを止めてから、サーバを再起動します。

$ ./gradlew bootrun Starting a Gradle Daemon (subsequent builds will be faster)

無事、削除ボタンが動きました。

参考

Spring Boot 2.2.0.RELEASE not mapping thymeleaf put and delete requests
After upgrading from Spring Boot 2.1.6.RELEASE to 2.2.0.RELEASE my Thymeleaf based pages are failing when performing puts and deletes on embedded Tomcat. Gets a...
タイトルとURLをコピーしました