はじめに
以下の書籍をやっていたところSpringBootのToDoリストの更新でエラーになったのでまとめます
問題
以下のコードを実行しました
TaskController.kt
@PatchMapping("{id}/")
fun update(@PathVariable("id") id: Long, @Validated form: TaskUpdateForm, bindingResult: BindingResult): String {
if (bindingResult.hasErrors())
return "tasks/edit"
val task = taskRepository.findById(id) ?: throw NotFoundException()
val newTask = task.copy(content = requireNotNull(form.content), done = form.done)
taskRepository.update(newTask)
return "redirect:/tasks"
}
edit.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>タスク編集</title>
</head>
<body>
<form th:method="patch" th:action="@{./}" th:object="${taskUpdateForm}">
<div>
<label>
内容: <input type="text" th:field="*{content}"/>
</label>
<p th:if="${#fields.hasErrors('content')}" th:errors="*{content}">エラーメッセージ</p>
</div>
<div>
<label>
完了: <input type="checkbox" th:field="*{done}"/>
</label>
</div>
<div>
<input type="submit" value="更新"/>
</div>
</form>
</body>
</html>
たしかにHTMLファイルを見た感じはth:method="patch"
になっていそうです
しかし更新をすると以下のログがでてPostメソッド
が実行されていることがわかります
| 2022-12-13T14:24:08.166Z DEBUG 296 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK
kotlin | 2022-12-13T14:24:10.133Z DEBUG 296 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : POST "/tasks/1/", parameters={masked}
kotlin | 2022-12-13T14:24:10.138Z WARN 296 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' is not supported]
kotlin | 2022-12-13T14:24:10.138Z DEBUG 296 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 405 METHOD_NOT_ALLOWED
kotlin | 2022-12-13T14:24:10.142Z DEBUG 296 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for POST "/error", parameters={masked}
kotlin | 2022-12-13T14:24:10.143Z DEBUG 296 --- [nio-8080-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
kotlin | 2022-12-13T14:24:10.148Z DEBUG 296 --- [nio-8080-exec-6] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
kotlin | 2022-12-13T14:24:10.150Z DEBUG 296 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 405
解決方法
以下の記事をみて原因がわかりました
いくつかの記事をたどっていくと、Spring Boot 2.2で、_method用フィルターがデフォルトで無効になり、それが原因のようです。
とあります。今回はSpring Boot3.0で行っているので該当しました
/src/main/resources/application.properties
に以下を追加するとPatchメソッド
になりました
/src/main/resources/application.properties
spring.mvc.hiddenmethod.filter.enabled=true
spring.webflux.hiddenmethod.filter.enabled=true
おわりに
Kotlinをはじめて色々エラーに遭遇するのでおわりに書くことがなくなってきました
今回は元の参考記事のまんまですがタイトルがわかりやすいようにして記事にしてみました