Найти

Вы здесь:

Пример в https://github.com/cherepakhin/hr_admin/blob/v0.0.6/src/main/java/net/guides/springboot2/freemarker/controller/PositionController.java

В проверяемом классе поле name должно быть от 3 до 15 символов, указано сообщение при ошибке:

@Entity
@Table(name = "positions")
public class Position {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Size(min = 3, max = 15, message = "Название должности должно быть от 3 to 15 символов.")
    @Column(nullable = false, unique = true, length = 15)
    private String name = "";

    public Position() {}
    ....
}
    

Контроллер. Внимание на аннотации @Validated , @Valid.

@Validated // добавляем валидацию!!!
@Controller
@RequestMapping("/positions")
public class PositionController {
        ....
    // POST /positions/update/{id} - обработка обновления
    @PostMapping("/update/{id}")
    public String updatePosition(@PathVariable Long id,
                                 @Valid @ModelAttribute Position position, // что валидируем
                                 BindingResult bindingResult,
                                 Model model) {
        String errors = "";
        log.info("Update position: {}", position);
        // Первый УРОВЕНЬ проверки - обработка ошибок @Valid.
        // Ошибки @Valid АВТОМАТИЧЕСКИ сохраняются в объекте bindingResult.
        if (bindingResult.hasErrors()) {
            // Обработка ошибок @Valid. Ошибки @Valid сохраняются в bindingResult.
            log.info("Binding result: {}", bindingResult);
            for (ObjectError error : bindingResult.getAllErrors()) {
                errors += error.getDefaultMessage() + "\n";
                log.error(error.getDefaultMessage());
            }
            model.addAttribute("name", position.getName());
            model.addAttribute("error_for_name", errors);
            position.setId(id); // Восстановление id для формы
            return NamesView.EDIT_POSITION;
        }
        // Второй УРОВЕНЬ проверки. Backend проверка.
        if (positionRepository.existsByName(position.getName())) {
            // Обработка backend ошибки
            log.error("Position with name {} already exists", position.getName());
            model.addAttribute("name", position.getName());
            model.addAttribute("error_for_name", "Должность с таким названием УЖЕ существует.");
        
	    // Другой способ сообщения об ошибке:
	    // Метод rejectValue() — мощный инструмент для реализации сложной бизнес-логики валидации.
	    // bindingResult.rejectValue("name", "error_for_name", "Должность с таким названием УЖЕ существует.");

            position.setId(id); // Восстановление id для формы
            return NamesView.EDIT_POSITION;
        }
        position.setId(id);
        positionRepository.save(position);
        return "redirect:/" + NamesView.POSITIONS + "/";
    }


Размещение сообщения об ошибке в форме:

<form action="${springMacroRequestContext.contextPath}/positions/update/${position.id}" method="post" class="p-6 space-y-4">
    <div>
        <label class="block text-base font-medium text-gray-700">Название</label>
        <input type="text"
               name="name"
               value="${position.name}"
               required
               class="mt-1 block w-full border border-gray-300 shadow-sm py-2 px-3 focus:outline-none focus:ring-sky-500 focus:border-sky-500">
        <#if error_for_name??>
        <p class="text-red-600 text-xs mt-1">${error_for_name}</p>
    </#if>
</div>


Для демонстрации пример упрощен (entity передается сразу в контроллер, нет сервисного слоя и т.д.).