首页 > 解决方案 > 在控制器中处理删除请求的正确方法是什么?

问题描述

尝试从 Thymeleaf 模板文件中发出删除 http 请求

从模板:

 <tr th:each="ingredient : ${listIngredients}">
                <td th:text="${ingredient.id}">IngredientID</td>
                <td th:text="${ingredient.name}">Name</td>
                <td th:text="${ingredient.description}">Description</td>
                <!-- <td th:text="${ingredient.img}">Img</td>
                <td th:text="${ingredient.ingredients}">Ingredients</td>
                <td th:text="${ingredient.preparation}">Preparation</td> -->
                <td>
                    <!-- <a th:href="@{'/edit/' + ${ingredient.id}}">Edit</a>
                    &nbsp;&nbsp;&nbsp; -->
                    <form th:object="${ingredient}" th:action="@{'/ingredients/' + ${ingredient.id}}" th:method="delete">
                        <button type="submit">Delete</button>
                    </form>
                </td>
            </tr>

从我的控制器:

@DeleteMapping("/ingredients/{ingredientId}")
    public String deleteIngredient(@PathVariable Long ingredientId, @ModelAttribute("ingredient") Ingredient ingredient){
            ingredientRepository.delete(ingredient);
            return "redirect:../../";
    }

带有保存按钮的表单模板:

<form action="#" th:action="@{/ingredients/ingredient/new/save}" th:object="${ingredient}"
            method="post">

            <table border="0" cellpadding="10">
                <tr>
                    <td>Ingredient Name:</td>
                    <td><input type="text" th:field="*{name}" /></td>
                </tr>
                <tr>
                    <td>Description:</td>
                    <td><input type="text" th:field="*{description}" /></td>
                </tr>

                <!-- <tr>
                    <td>Tags:</td>
                    <td><input type ="text" th:field="*{tags}" /></td>
                </tr> -->

                <tr>
                    <td colspan="2"><button type="submit">Save</button> </td>

在控制器中保存方法:


    @RequestMapping(value = "/ingredient/new/save", method = RequestMethod.POST)
    public String saveIngredient(@ModelAttribute("ingredient") Ingredient ingredient){
        ingredientRepository.save(ingredient);
        return "redirect:../../";
    }

成分实体:

package com.donovanuy.mixmix.entities;

import java.util.*;

import javax.persistence.*;

@Entity
@Table(name = "ingredients_master")
public class Ingredient extends AuditModel{

    @Column(name = "ingredient")
    private String name;
    @Column(name="description")
    private String description;

    @Id
    @GeneratedValue
    private long id;

    // public Ingredient(String n, String d){
    //     this.setName(n);
    //     this.setDescription(d);
    // }

    // public Ingredient(int id, String n, String d){
    //     this.setId(id);
    //     this.setName(n);
    //     this.setDescription(d);
    // }


    @ManyToMany(mappedBy = "ingredients")
    Set<UserRecipe> recipes;

    @ManyToMany
    Set<Tag> tags;


// Setters
}

更新

现在一切都按预期工作,我将 DELETE 请求隐藏在我的模板文件中,并在我的 repo 中创建了一个 deleteById 方法。

形式

<form th:action="@{'/ingredients/ingredient/' + ${ingredient.id}}" th:method="POST">
                        <input type="hidden" name ="_method" value="DELETE" />
                        <button type="submit">Delete</button>
                    </form>

控制器:

@DeleteMapping("/ingredients/ingredient/{ingredientId}")
    public String deleteIngredient(@PathVariable Long ingredientId){
            ingredientRepository.deleteById(ingredientId);
            return "redirect:../";
    }

存储库:

import org.springframework.data.jpa.repository.JpaRepository;


import com.donovanuy.mixmix.entities.Ingredient;
import java.util.List;


public interface IngredientRepository extends JpaRepository<Ingredient, Long> {
    List<Ingredient> findAllById(Long id);

    public void deleteById(Long Id);
}

标签: javahibernateormspring-data-jpathymeleaf

解决方案


这里的主要问题是只有GETPOST方法在 HTML 表单提交(详细信息)中有效。您可以通过使用 Spring 的HiddenHttpMethodFilter来解决这个问题。有了它,您可以使用标记:

<form th:action="@{'/ingredients/' + ${ingredient.id}}" method="POST">
  <input type="hidden" name="_method" value="DELETE" />
  <button type="submit">Delete</button>
</form>

对于控制器部分,deleteById(...)在存储库中添加一个方法。那么控制器代码可以是:

@DeleteMapping("/ingredients/{ingredientId}")
public String deleteIngredient(@PathVariable Long ingredientId) {
    ingredientRepository.deleteById(ingredientId);
    return "redirect:../../";
}

推荐阅读