LoginSignup
21
15

More than 3 years have passed since last update.

SpringBoot2.2+ThymeleafでHTTP PUT/DELETE メソッドを扱う

Last updated at Posted at 2020-02-01

SpringMVCのControllerではHTTPメソッドとしてPUT/DELETEを扱うことが出来ますが、HTML5ではいまだにこれらのHTTPメソッドを扱うことができません。
このギャップを埋めるためにこれまでは、

  • ControllerのマッピングではPUT/DELETEメソッドへのマッピングを定義する
Controller.java
@Controller
@RequestMapping("/item")
public class ItemController {
    ...
    @DeleteMapping("{id}")
    public String delete(@PathVariable("id") Long id) {
        service.delete(id);
        return "redirect:/item";
    }
}
  • thymeleaf側でput/deleteメソッドのフォームを定義するとpostに置き換えて_methodというhiddenパラメータを埋め込む
template.html
<form th:action="@{/item/{id}(id=*{id})}" th:method="delete">
    <input type="submit" value="delete" />
</form>
rendered.html
<form action="/item/1" method="post">
    <input type="hidden" name="_method" value="delete" />
    <input type="submit" value="delete" />
</form>
  • HiddenHttpMethodFilterというフィルタでこのhiddenパラメータを検知するとリクエストメソッドを差し替える

というアプローチを取っていました。

SpringBoot 2.1 までは、この HiddenHttpMethodFilter がデフォルトの AutoConfiguration で有効化されていたため、特に意識することなく利用できていましたが、SpringBoot 2.2 からデフォルトの挙動が変わり、オフになったようです。

Spring Boot 2.2 Release Notes: HttpHiddenMethodFilter disabled by default

リリースノートによると、

it causes early consumption of a request body if the body may contain parameters.

ということで、early consumption が何を指すのかは理解できなかったのですが、やりたいことに対してフィルタを噛ませるオーバーヘッドのデメリットの方が大きいという感じなのでしょうか。
HTMLでPUT/DELETEがサポートされる気配はないですし、REST APIでもないHTMLなWebサイトから無理にPUT/DELETEメソッド使う必要もないでしょうみたいな話なのかもしれません。

HttpHiddenMethodFilterを使いたい場合は、Configurationで有効にしてあげれば良いとのこと。

application.yml
spring.mvc.hiddenmethod.filter.enabled: true

これでこれまで通りHTMLからPUT/DELETEメソッドを利用することができます。
ですが、SpringBootのデフォルトでdisabledになったということはあまり使わないほうがいいのでしょうかね。

追記

なぜデフォルトから外されたのか。という点について。
以下のIssueあたりで議論されていました。

https://github.com/spring-projects/spring-boot/issues/16953
https://github.com/spring-projects/spring-boot/issues/18088

ざっくりまとめると

  • テンプレートエンジンを使用せずAPIとして利用するなら不要
  • MultipartFileがリクエストパラメータに含まれていた場合にフィルタの処理に時間がかかっている
  • MaxUploadSizeを超えるエラーが起きた場合にFilterでエラーを投げてしまうためMVCでハンドリングできない

というあたりが理由のようです。
このあたりを踏まえて問題ない場合に有効にするのがよさそう。

21
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
15