请求方式'POST'不支持]

Request method 'POST' not supported]

我的 updatePowerPlant() 方法有问题,当我尝试更新具有给定 ID 的 powerPlant 实体并单击 localhost:8080/updatePowerPlant 地址下更新表单中的提交按钮时,我被重定向到此 url http://localhost:8080/updatePowerPlant/savePowerPlant.

我不知道为什么。我应该重定向到 /powerPlants,无论具有给定 ID 的实体是否存在,而是将 /savePowerPlant 添加为 url localhost:8080/updatePowerPlant 的最后一部分,我得到 Request 方法 'POST'不支持],我知道这是我应该得到的消息,毕竟没有这样的 url 的 GetController 但为什么我得到这个奇怪的 url?是不是因为我用GetController来更新?

localhost:8080/updatePowerPlant 我在浏览器中输入这个来获取更新表单 http://localhost:8080/updatePowerPlant/savePowerPlant 这是我在更新表单中点击提交时得到的

控制器class

@RequiredArgsConstructor
@Controller
public class PowerPlantsController {


    private final PowerPlantRepository powerPlantRepository;
    private final EventRepository eventRepository;
    private final PlantService plantService;
    private final EventService eventService;


    @GetMapping("form")
    public String getForm(Model model) {
        model.addAttribute("plant", new PlantViewModel());
        return "save";
    }


    @PostMapping("savePowerPlant")
    public String addPowerPlant(@ModelAttribute("plant") @Valid PlantViewModel plant, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            if (plant.getId() == null) {
                return "save";
            } else return "updatePowerPlant";
        }
        if (plant.getId() == null){
            plantService.add(plant);
        }else {
            plantService.update(plant);
        }
        return "redirect:/powerPlants";
    }


    @GetMapping("updatePowerPlant/{id}")
    public String updatePowerPlant(@PathVariable(value = "id") Integer id, Model model) {
        var find = powerPlantRepository.getOne(id);
        var plants = plantService.powerPlantToViewModel(find);
        model.addAttribute("plant", plants);
        return "updatePowerPlant";
    }


    @ResponseBody
    @GetMapping("failures/{id}")
    public long failures(@PathVariable("id") int id) {
        return eventService.NumberOfFailureEventsForId(id);
    }


    @ResponseBody
    @GetMapping("powerPlants")
    public List<PowerPlant> findAll() {
        return powerPlantRepository.findAll();
    }


    @GetMapping("powerPlants/{id}")
    public String findById(@PathVariable("id") Integer id, Model model) {
        model.addAttribute("plant", powerPlantRepository.getOne(id));

        return "plant";
    }


    @GetMapping("delete/powerPlants")
    public String deleteById(@RequestParam(value = "id") Integer id) {
        powerPlantRepository.deleteById(id);
        return "redirect:/powerPlants";
    }

    @GetMapping("addEventToPlant")
    public String addEventToPlant(@RequestParam(value = "plantId") Long plantId, @RequestParam(value = "eventId")
            Long eventId, Model model) {


        if (powerPlantRepository.findById(Math.toIntExact(plantId)).isPresent()
                && eventRepository.findById(Math.toIntExact(eventId)).isPresent()) {
            var pl = powerPlantRepository.getOne(Math.toIntExact(plantId));
            var ev = eventRepository.getOne(Math.toIntExact(eventId));

            var eventsForPlant = pl.getEvents();
            eventsForPlant.add(ev);
            pl.setEvents(eventsForPlant);

            powerPlantRepository.save(pl);
        }

        var t = powerPlantRepository.getOne(Math.toIntExact(plantId)).getEvents();
        model.addAttribute("plant", t);

        return "plant_events";
    }
}

服务class

@org.springframework.stereotype.Service
@RequiredArgsConstructor
public class PlantService implements powerForPowerPlantPerDay, Add, PlantServiceToViewModel {


    private final EventRepository eventRepository;
    private final PowerPlantRepository powerPlantRepository;

    public Map<Integer, String> powerForPowerPlantPerDay(Timestamp date) {
        List<Event> list = new ArrayList<>(getAllEvents());
        Map<Integer, String> map = new HashMap<>();
        list.stream()
                .filter(e -> e.startDate.equals(date))
                .forEach(e -> map.put(e.id, e.typeOfEvent));
        return map;
    }


    public Collection<Event> getAllEvents() {
        return eventRepository.findAll();
    }


    public void add(PlantViewModel plantViewModel) {
        var p = PowerPlant.builder().
                name(plantViewModel.getName())
                .power(plantViewModel.getPower())
                .events(plantViewModel.getListOfEventsForPlant())
                .build();
        powerPlantRepository.save(p);
    }

    public PlantViewModel powerPlantToViewModel(PowerPlant powerPlant) {
        return PlantViewModel.builder()
                .id(powerPlant.getId())
                .name(powerPlant.getName())
                .power(powerPlant.getPower())
                .build();

    }


    public PowerPlant update(PlantViewModel plantViewModel) {
        var plant = powerPlantRepository.getOne(plantViewModel.getId());

        plant.setName(plantViewModel.getName());
        plant.setPower(plantViewModel.getPower());

        return powerPlantRepository.save(plant);
    }
}

更新html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
    <h1>Update</h1>
    <hr>
    <h2>Update powerPlant</h2>

    <form action="#" th:action="@{savePowerPlant}" th:object="${plant}" method="POST">
        <input id="studentId" th:value="${plant.id}" type="hidden" th:field="*{id}">
        <div th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Invalid Name</div>
        <input type="text" th:field="*{name}" placeholder="Name" class="form-control mb-4 col-4">

        <div th:if="${#fields.hasErrors('power')}" th:errors="*{power}">Invalid power</div>
        <input type="text" th:field="*{power}" placeholder="power" class="form-control mb-4 col-4">


        <button type="submit" class="btn btn-info col-2">Save</button>
    </form>
    <hr>
</div>
</body>
</html>

保存html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>New Student</title>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
    <h1>Save</h1>
    <hr>
    <h2>Save powerPlant</h2>

    <form action="#" th:action="@{savePowerPlant}" th:object="${plant}" method="POST">
        <div th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Invalid Name</div>
        <input type="text" th:field="*{name}" placeholder="Name" class="form-control mb-4 col-4">

        <div th:if="${#fields.hasErrors('power')}" th:errors="*{power}">Invalid power</div>
        <input type="text" th:field="*{power}" placeholder="power" class="form-control mb-4 col-4">

        <button type="submit" class="btn btn-info col-2">Save</button>
    </form>
    <hr>
</div>
</body>
</html>

正如您在文档中看到的 here,您在 th:action 中使用了相对 URL。这些会附加到地址栏中的当前 URL。

所以 th:action="@{savePowerPlant}" 结果是 current/URL/savePowerPlant

简单的解决方案是通过完全输入 (http://localhost:portNumber/savePowerPlant) 或使用相对服务器 URL: th:href="@{~/savePowerPlant} 来切换到绝对 URLs。