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=trueCode language: plaintext (plaintext)

を記述します。

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

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

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

参考

Forbidden - Stack Exchange
タイトルとURLをコピーしました