尝试通过百里香进行Spring Boot表单验证,但收到我无法弄清的错误

时间:2019-12-06 02:52:13

标签: java spring-boot thymeleaf

编辑:该页面现在可以正常运行,并且我更新了以下代码以反映我的更改。问题是我需要在网页的GetMapping中将Booking属性添加到模型中。我还需要更正网页上的表单标签。

我有一个演示Web应用程序,我正在尝试在表单上添加错误检查以及错误消息,错误消息将在接下来的相关输入中显示。但是,在实现我发现的here方法之后,当我尝试使用要为其实现验证的形式导航到网页时,出现白色标签错误页面。它说"Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'Booking' available as request attribute"

这是有问题的网页:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Reserve Booking</title>
</head>
<body>
    <h1>Reserve Booking</h1>
    <form th:object="${Booking}">
        <label for="flightId">Flight ID</label>
        <input name="flightId" type="text" th:field="*{flightId}"/>
        <label th:if="${#fields.hasErrors('flightId')}" th:errors="*{flightId}">Flight ID Error</label>
        </br>
        <label for="seatNum">Seat Number</label>
        <input name="seatNum" type="text" th:field="*{seatNum}"/>
        <label th:if="${#fields.hasErrors('seatNum')}" th:errors="*{seatNum}">Seat Number Error</label>
        </br>
        <input type="submit" formmethod="post" value="Submit"/>
        </br>
        <button formaction="/index.html">Back to Index</button>
    </form >
</body>
</html>

这里是Booking类,它使用Lombok进行获取和安装程序操作:

@Data
public class Booking {
    String confNum;

    @NotBlank(message = "Must enter a flight ID")
    @Size(min = 3, max = 3, message = "Flight ID must be 3 digits in length")
    String flightId;

    @NotBlank(message = "Must select a seat number")
    @Size(min = 1, max = 2)
    String seatNum;

    public Booking(){
        UUID uuid = UUID.randomUUID();
        confNum = uuid.toString().substring(0,5);
    }
}

这是控制器的相关代码:

@Controller
@RequestMapping(value = "/booking")
public class BookingController{
    @Autowired
    BookingData bookingData;

    @GetMapping(value = "/reserve")
    public String ReserveHandler(Model model){
        if(!model.containsAttribute("Booking")){
            model.addAttribute("Booking", new Booking());
        }
        return "booking/reserve";
    }

    @PostMapping(value = "/reserve")
    public String ReserveSeat(
        @Valid @ModelAttribute("Booking") Booking booking, 
        BindingResult bindingResult, 
        Model model
    ){
        String redirect;

        if(bindingResult.hasErrors()){
            redirect = "booking/reserve";
        }else{
            model.addAttribute("bookingList", bookingData.getAllBookings());
            bookingData.addNewBooking(booking);
            redirect = "booking/show";
        }

        return redirect;
    }
}

在尝试对表单实施错误检查之前,一切工作都很好。错误检查与BookingData无关,这就是为什么我没有包含它的原因。它只是有一个已预订座位的数组列表以及用于返回列表以及从中添加和删除列表的方法。

1 个答案:

答案 0 :(得分:3)

您没有在控制器中添加模型以匹配表单中的th:Object。您需要在ReserveHandler中添加模型属性。我不确定最近的变化(如果有的话),但是我之前已经做过(在这种情况下使用一些模型名称):

public String myGetRequest(Model model) {
    if (!model.containsAttribute("Booking")) {
        // Add the named model attribute here
        model.addAttribute("Booking", new Booking());
    }
    return "booking/reserve";
}

@PostMapping(...)
public String myPostRequest(
    @Valid @ModelAttribute Booking booking,
    final BindingResult bindingResult,
    final RedirectAttributes redirectAttributes
) {
    if (bindingResult.hasErrors()) {
        // Adds the validation errors
        redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.Booking", bindingResult);

        // Set the model attribute
        redirectAttributes.addFlashAttribute("Booking", booking);
        return "redirect:/booking/reserve";
    }
    // Otherwise...
    return "redirect:/booking/show";
}