Обработка ошибок с формы в контроллере

Рейтинг: -2Ответов: 1Опубликовано: 29.03.2023

Есть форма

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" th:href="@{/styles/css/style.css}"/>
    <link rel="stylesheet" th:href="@{/styles/css/fontawesome.min.css}"/>
    <link rel="stylesheet" href="/webjars/bootstrap/5.2.0/css/bootstrap.min.css"/>
    <script th:src="@{/js/fontawesome.min.js}" type="text/javascript"></script>
    <title>title</title>
</head>
<body>

<div class="container">

        <h1>title</h1>

        <div class="form_wrapper">
            <form th:method="POST">

                <div class="dates_wrapper">
                    <input class="dates_class" type="date" id="bgnDate" placeholder="Дата начала расчета"/>
                    <input class="dates_class" type="date" id="endDate" placeholder="Дата конца расчета"/>
                </div>

                <div class="otd_checks_wrapper">
                    <input type="checkbox" class="custom-checkbox" id="chk1" name="chk1"/>
                    <chk5el for="chk1">chk1</chk5el>
                    <input type="checkbox" class="custom-checkbox" id="chk2" name="chk2"/>
                    <chk5el for="chk2">chk2</chk5el>
                    <input type="checkbox" class="custom-checkbox" id="chk3" name="chk3"/>
                    <chk5el for="chk3">chk3</chk5el>
                    <input type="checkbox" class="custom-checkbox" id="chk4" name="chk4"/>
                    <chk5el for="chk4">chk4</chk5el>
                    <input type="checkbox" class="custom-checkbox" id="chk5" name="chk5"/>
                    <chk5el for="chk5">chk5</chk5el>
                    <input type="checkbox" class="custom-checkbox" id="chk6" name="chk6"/>
                    <chk5el for="chk6">chk6</chk5el>
                    <input type="checkbox" class="custom-checkbox" id="chk7" name="chk7"/>
                    <chk5el for="chk7">chk7</chk5el>
                </div>

                <div class="other_settings_wrapper">
                    <input type="checkbox" class="custom-checkbox" id="chk8" name="chk8"/>
                    <chk5el for="chk8">chk8</chk5el>
                </div>

                <input type="submit" value="Запустить" name="startButton">
            </form>
        </div>

</div>

<script type="text/javascript" src="/webjars/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/5.2.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/5.2.0/js/bootstrap.bundle.min.js"></script>

</body>
</html>

А также контроллер

@Controller
public class MainController {

    @Autowired
    public MainController() {
    }

    @GetMapping("/")
    public String main() {
        return "index";
    }

    @PostMapping("/")
    public String start(@RequestParam(required = false) boolean chk1,
                        @RequestParam(required = false) boolean chk2,
                        @RequestParam(required = false) boolean chk3,
                        @RequestParam(required = false) boolean chk4,
                        @RequestParam(required = false) boolean chk5,
                        @RequestParam(required = false) boolean chk6,
                        @RequestParam(required = false) boolean chk7
                        ) {

        if (!chk1 && !chk2 && !chk3 && !chk4 && !chk5 && !chk6 && !chk7) {
            System.out.println("Выберите хотя бы что-то!");
        }

        return "redirect:/";
    }

}

Если не выбран ни один чек бокс из chk1-chk7 или если поля дат пустые, как форме отобразить сообщение чтобы нужно выбрать хотя бы один чекбокс или указать даты? Нужно именно из контроллера обратно в форму передать такую ошибку.

Ответы

▲ 1Принят

Форма. Чекбоксы с одинаковым атрибутом name будут обрабатываться как массив, элементы которого будут устанавливаться в соотвествии с атрибутом value. Элемент с атрибутом th:if="${dateError}" будет рендериться только если dateError установлен в 'true'.

<form th:method="post" action="/">
    <div class="dates_wrapper">
        <p th:if="${dateError}" style="color:red">Укажите даты</p>
        <input class="dates_class" type="date" name="beginDate" placeholder="Дата начала расчета"/>
        <input class="dates_class" type="date" name="endDate" placeholder="Дата конца расчета"/>
    </div>
    <div class="otd_checks_wrapper">
        <p th:if="${checkingError}" style="color:red">Выберите хотя бы один пункт</p>
        <input type="checkbox" class="custom-checkbox" id="chk1" name="check" value="1"/>
        <label for="chk1">chk1</label>
        <input type="checkbox" class="custom-checkbox" id="chk2" name="check" value="2"/>
        <label for="chk2">chk2</label>
        <input type="checkbox" class="custom-checkbox" id="chk3" name="check" value="3"/>
        <label for="chk3">chk3</label>
        <input type="checkbox" class="custom-checkbox" id="chk4" name="check" value="4"/>
        <label for="chk4">chk4</label>
        <input type="checkbox" class="custom-checkbox" id="chk5" name="check" value="5"/>
    </div>
    <input type="submit" value="Запустить" name="startButton">
</form>

Контроллер. Если в форме не был выбран элемент, то в качестве соответсвуещего аргумента в метод будет передоваться null.

@Controller
public class MainController {

    @GetMapping("/")
    public String index() {
        return "index";
    }

    @PostMapping("/")
    public String post(
            @RequestParam(required = false) String[] check,
            @RequestParam(required = false) LocalDate beginDate,
            @RequestParam(required = false) LocalDate endDate,
            RedirectAttributes redirectAttributes
    ) {

        boolean datesSelected = datesSelected(beginDate, endDate);
        boolean checkboxSelected = checkboxSelected(check);

        if (!datesSelected) {
            redirectAttributes.addFlashAttribute("dateError", true);
        }

        if (!checkboxSelected) {
            redirectAttributes.addFlashAttribute("checkingError", true);
        }

        if (datesSelected && checkboxSelected) {
            for (String selection : check) {
                System.out.printf("processing [%s]: from %s to %s%n",
                        selection, beginDate, endDate);
            }
        }

        return "redirect:/";
    }

    private boolean datesSelected(LocalDate beginDate, LocalDate endDate) {
        return beginDate != null && endDate != null;
    }

    private boolean checkboxSelected(String[] checkboxes) {
        return checkboxes != null;
    }

}