背景
Spring Bootでは@PutMapping
や@DeleteMapping
などを使うことでPUT/DELETEメソッドのHTTPリクエストを受け取ることができます。
一方でHTML5では、PUT/DELETEメソッドを送信することができないため、直接HTMLからサーバにリクエストを投げる場合には、HTMLからPOSTリクエストを送り、サーバ側でPUT/DELETEに変換する必要があります。
今回は、Spring BootとThyemeleafを使ったアプリケーションで、POSTリクエストをPUT/DELETEに変換する方法を説明します。
環境
- Kotlin 1.3
- Spring Boot 2.3.4.RELEASE
方法
HTML側の設定
HTML側は、formタグのth:methodにput
もしくはdelete
を設定します。
<form th:action="@{/todo/{id}(id=${todo.getId()})}" th:method="delete"> <button type="submit">delete</button> </form>
実際にレンダリングされると、以下のように_method
というhiddenパラメータをPOSTリクエストで送信するようになります。
<form action="/todo/1" method="post"> <input type="hidden" name="_method" value="delete"> <button type="submit" class="btn btn-primary">delete</button> </form>
サーバ側の設定
Spring Bootで作成したController側では、PUT/DELETEで実行させたいハンドラを実装します。
@Controller @RequestMapping class TodoController(private val todoDeleteService: TodoDeleteService) { // 省略 @DeleteMapping("todo/{id}") fun delete(@PathVariable id: String, modelAndView: ModelAndView): ModelAndView { todoDeleteService.deleteTodo(id) modelAndView.viewName = "redirect:/" return modelAndView } }
次に、HTMLから送られた_method
というhiddenパラメータを含むPOSTリクエストを、このDELETE用のハンドラに変換する処理を行うHiddenHttpMethodFilter
を有効化します。
Spring Boot 2.2系からはHiddenHttpMethodFilter
がデフォルトで無効になっているので、設定ファイルに以下を追加します。
spring.mvc.hiddenmethod.filter.enabled=true
Spring MVCの設定をカスタマイズするために, WebMvcConfigurationSupportを継承したConfigurationクラスを利用している場合は、
設定ファイルから有効化する代わりに、以下のように自前でHiddenHttpMethodFilter
のインスタンスをBeanに登録しておきます。
@Configuration class ApplicationConfiguration : WebMvcConfigurationSupport() { // 省略 // PUT, DELETEメソッドに変換するServletFilterをBeanとして設定 @Bean fun hiddenHttpMethodFilter(): FilterRegistrationBean<HiddenHttpMethodFilter> { val filterRegistrationBean = FilterRegistrationBean(HiddenHttpMethodFilter()) filterRegistrationBean.urlPatterns = listOf("/*") return filterRegistrationBean } }
以上をおこなうことで、HTMLからのPOSTリクエストをPUT/DELETEメソッドに変換して、対応するハンドラを実行させることができます。
参考
Spring Boot Reference Documentation
java - Spring Boot how to use HiddenHttpMethodFilter - Stack Overflow