简体   繁体   中英

What is the proper way to handle a delete request in a controller?

Trying to make a delete http request from Thymeleaf template file

From template:

 <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>

From my controller:

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

Form template with save button:

<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>

Save method in controller:


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

Ingredient Entity:

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
}

UPDATE

Everything now works as intended, I made the DELETE request hidden in my template file, and created a deleteById method in my repo.

Form

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

Controller:

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

Repository:

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);
}

The main problem here is that only GET and POST methods are valid in HTML form submissions ( details ). You can work-around that by utilising Spring's HiddenHttpMethodFilter . With that in place, you can use markup:

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

For the controller part, add a deleteById(...) method in the repository. Then the controller code can be:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM