Пружинный загрузочный лист thymeleaf (поле.hasError всегда ложно)

#spring #spring-boot #thymeleaf

#весна #пружинный ботинок #тимелиаф

Вопрос:

Я создаю веб-приложение, и как часть моего приложения я использую Spring boot с Thymeleaf.

Весенняя версия: 2.5.6, JDK: 17

Когда я пытаюсь отправить форму с некоторыми ожидаемыми ошибками при вводе, результат привязки идентифицирует ошибки и печатается в контроллере, но в Thymeleaf, когда я проверяю наличие ошибок, ничего не отображается.

POM.XML

 lt;propertiesgt;  lt;project.build.sourceEncodinggt;UTF-8lt;/project.build.sourceEncodinggt;  lt;project.reporting.outputEncodinggt;UTF-8lt;/project.reporting.outputEncodinggt;  lt;java.versiongt;17lt;/java.versiongt; lt;/propertiesgt;  lt;parentgt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-parentlt;/artifactIdgt;  lt;versiongt;2.5.6lt;/versiongt;  lt;relativePath /gt; lt;/parentgt;  lt;dependenciesgt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-weblt;/artifactIdgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-data-jpalt;/artifactIdgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-validationlt;/artifactIdgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-securitylt;/artifactIdgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-devtoolslt;/artifactIdgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-thymeleaflt;/artifactIdgt;  lt;/dependencygt;   lt;dependencygt;  lt;groupIdgt;mysqllt;/groupIdgt;  lt;artifactIdgt;mysql-connector-javalt;/artifactIdgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.projectlomboklt;/groupIdgt;  lt;artifactIdgt;lomboklt;/artifactIdgt;  lt;scopegt;providedlt;/scopegt;  lt;/dependencygt; lt;/dependenciesgt;  

Применение.свойства

 spring.datasource.url=jdbc:mysql://localhost:3306/unknown spring.datasource.username=root spring.datasource.password=root spring.datasource.testWhileIdle=true spring.datasource.validationQuery=SELECT 1  spring.jpa.show-sql=true  spring.jpa.hibernate.ddl-auto=update  spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect  spring.sql.init.mode=never  spring.thymeleaf.cache=false spring.thymeleaf.check-template=true spring.thymeleaf.check-template-location=true spring.thymeleaf.enabled=true spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html  logging.level.org.springframework=INFO logging.level.org.thymeleaf=ERROR logging.level.org.springframework.boot=ERROR  

HMTL с листом тимьяна:

 lt;form class="row mb-0" action="#" th:action="@{/post}" th:object="${formData}" method="post"gt;   lt;div class="col-md-6 form-group"gt;  lt;label for="name"gt;Name lt;smallgt;*lt;/smallgt;lt;/labelgt;  lt;label th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="validation-message"gt;lt;/labelgt;  lt;input type="text" id="name" th:field="*{name}" class="sm-form-control" /gt;  lt;/divgt;   lt;div class="col-md-6 form-group"gt;  lt;label for="email"gt;Email lt;smallgt;*lt;/smallgt;lt;/labelgt;  lt;label th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="validation-message"gt;lt;/labelgt;  lt;input type="email" id="email" th:field="*{email}" class="sm-form-control" /gt;  lt;/divgt;   lt;div class="w-100"gt;lt;/divgt;   lt;div class="col-md-6 form-group"gt;  lt;label for="phone"gt;Phonelt;/labelgt;  lt;label th:if="${#fields.hasErrors('phone')}" th:errors="*{phone}" class="validation-message"gt;lt;/labelgt;  lt;input type="text" id="phone" th:field="*{phone}" class="sm-form-control" /gt;  lt;/divgt;   lt;div class="col-md-6 form-group"gt;  lt;label for="service"gt;Serviceslt;/labelgt;  lt;label th:if="${#fields.hasErrors('service')}" th:errors="*{service}" class="validation-message"gt;lt;/labelgt;  lt;select id="service" class="sm-form-control" th:field="*{service}" gt;  lt;option value=""gt;-- Select One --lt;/optiongt;  lt;option th:each="service : ${T(com.utterlydesi.web.constant.Service).values()}"  th:value="${service}"  th:text="${service}"gt;service  lt;/optiongt;  lt;/selectgt;  lt;/divgt;   lt;div class="w-100"gt;lt;/divgt;   lt;div class="col-12 form-group"gt;  lt;label for="title"gt;Title lt;smallgt;*lt;/smallgt;lt;/labelgt;  lt;div class="alert alert-warning" th:if="${#fields.hasErrors('title')}" th:errors="*{title}"gt;lt;/divgt;  lt;input type="text" id="title" th:field="*{title}" class="sm-form-control" /gt;  lt;/divgt;   lt;div class="col-12 form-group"gt;  lt;label for="description"gt;Description lt;smallgt;*lt;/smallgt;lt;/labelgt;  lt;div class="alert alert-warning" th:if="${#fields.hasErrors('description')}" th:errors="*{description}"gt;lt;/divgt;  lt;textarea class="required sm-form-control" id="description" name="template-contactform-message" rows="6" cols="30" th:field="*{description}"gt;lt;/textareagt;  lt;/divgt;   lt;div class="col-12 form-group"gt;  lt;button class="button button-3d m-0" type="submit" id="add-post-submit" value="submit" th:text="Submit"gt;lt;/buttongt;  lt;/divgt;    lt;div th:if="${result != null}"gt;  lt;span class="alert alert-primary" role="alert" th:utext="${result}"gt;lt;/spangt;  lt;/divgt;   lt;ul th:if="${#fields.hasErrors('*')}"gt;  lt;li th:each="error : ${#fields.errors('*')}" th:text="${error}"gt;errorlt;/ligt;  lt;/ulgt;   lt;ul th:if="${#fields.hasErrors('global')}"gt;  lt;li th:each="error : ${#fields.errors('global')}" th:text="${error}"gt;errorlt;/ligt;  lt;/ulgt;  lt;/formgt;  

Controller:

 @Controller public class PostController {   @GetMapping(value = {"/post"})  public String post(Model model) {  model.addAttribute("formData", new PostAdd());  return "post";  }   @PostMapping("/post")  public String addPost(@ModelAttribute("formData") @Valid PostAdd formData, BindingResult bindingResult, Model model) {  try {  System.out.println(formData.toString());  if (bindingResult.hasErrors()) {  System.out.println("2");  System.out.println(bindingResult.hasErrors()   " "   bindingResult.hasFieldErrors("description"));  System.out.println(model.asMap());  model.addAttribute("result", "There was an issue with registration. Please corrected the fields highlighted in red");  return "post";  } else {  System.out.println("3");  //model.addAttribute(POST_ADD_OBJ_KEY, new PostAdd());  //model.addAttribute("result", "Post added successfully");  }   System.out.println(bindingResult.hasErrors()   " "   bindingResult.hasFieldErrors("description"));  return "redirect:/index";  } catch (Exception e) {  e.printStackTrace();  return "redirect:/index";  }  }   public PostController() {   } }  

PostAdd.java

 @Data public class PostAdd {   @NotEmpty(message = "*Please provide a name")  private String name;   @Email(message = "*Please provide a valid Email")  @NotEmpty(message = "*Please provide an email")  private String email;   @Length(min = 10, message = "*Your phone number must have at least 10 characters")  @NotEmpty(message = "*Please provide a valid phone number")  private String phone;   @NotNull(message = "*Please select a valid service")  private Service service;   @Length(min = 5, message = "*Please add a more descriptive title")  @NotEmpty(message = "*Please provide a title")  private String title;   @Length(min = 100, message = "*Please make your description more descriptive. At least 100 characters is required")  @NotEmpty(message = "*Please enter description")  private String description; }  

Вывод SOP из контроллера:

 PostAdd(name=First Middle Last, email=fml@gmail.com, phone=11111111111, service=null, title=11, description=111) 2 true true {formData=PostAdd(name=First Middle Last, email=fml@gmail.com, phone=10123456789, service=null, title=11, description=111), org.springframework.validation.BindingResult.formData=org.springframework.validation.BeanPropertyBindingResult: 3 errors Field error in object 'formData' on field 'description': rejected value [111]; codes [Length.formData.description,Length.description,Length.java.lang.String,Length]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [formData.description,description]; arguments []; default message [description],2147483647,100]; default message [*Please make your description more descriptive. At least 100 characters is required] Field error in object 'formData' on field 'service': rejected value [null]; codes [NotNull.formData.service,NotNull.service,NotNull.com.utterlydesi.web.constant.Service,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [formData.service,service]; arguments []; default message [service]]; default message [*Please select a valid service] Field error in object 'formData' on field 'title': rejected value [11]; codes [Length.formData.title,Length.title,Length.java.lang.String,Length]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [formData.title,title]; arguments []; default message [title],2147483647,5]; default message [*Please add a more descriptive title]}  

Что я пробовал до сих пор, основываясь на некоторых других сообщениях, которые я видел в Stackoverflow?

  • Понижение рейтинга до JDK 8
  • Понижение до версии Spring boot менее 2.3.0
  • Добавить @EnableWebMvc
  • Заменил @PostMapping на @RequestMapping
  • Поменялись местами @Valid с атрибутом @ModelAttribute

Комментарии:

1. На первый взгляд я не вижу ничего явно неправильного. Может быть, вы можете создать пример проекта на GitHub, в котором будет показана проблема?

2. Я постараюсь создать его, как только представится возможность