绑定结果显示Whitelabel错误页



我有一个thymelaf表单,可以在其中向父类别添加子类别:

<div th:if="${parentCategories.size() == 0}">
<span>There are no categories, please, add some categories!</span>
</div>
<div th:unless="${parentCategories.size() == 0}">
<label for="subcategoryForm">Add a subcategory</label>
<form id="subcategoryForm" th:action="@{/category/add-subcategory}" th:object="${category}" method="post">
<label for="name">Category name</label>
<input id="name" type="text" th:field="*{categoryName}"/>
<span th:if="${#fields.hasErrors('categoryName')}" th:errors="*{categoryName}" th:errorclass="error"></span>
<label for="selectParentCategory">Enter a parent category</label>
<select id="selectParentCategory" th:field="*{parentCategoryName}">
<option th:each="category : ${parentCategories}"
th:value="${category.categoryName}"
th:text="${category.categoryName}"/>
<span th:if="${#fields.hasErrors('parentCategoryName')}" th:errors="*{parentCategoryName}" th:errorclass="error"></span>
</select>
<button type="submit">Add category</button>
</form>
</div>

我有一个分类DTO:

@Setter
@Getter
public class CategoryDTO {
@CategoryValidator
private String categoryName;
@ParentCategoryValidator
private String parentCategoryName;
}

@CategoryValidator由CategoryValidatorImpl:验证

@Autowired
private CategoryRepository categoryRepository;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(value.isBlank()){
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("{categoryDTO.blank}").addConstraintViolation();
return false;
}
Optional<Category> optionalCategory = categoryRepository.findByName(value);
if (optionalCategory.isPresent()) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("{categoryDTO.alreadyExists}").addConstraintViolation();
return false;
}
Pattern pattern = Pattern.compile("[a-zA-Z\s]*");
Matcher matcher = pattern.matcher(value);
if (!matcher.matches()) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("{categoryDTO.name.invalid}").addConstraintViolation();
return false;
}
return true;
}

类别控制器的一部分:

@GetMapping("/subcategory-form")
public String getSubcategoryForm(Model model){
List<CategoryDTO> listOfParentCategories = categoryService.getParentCategories();
model.addAttribute("category", new CategoryDTO());
model.addAttribute("parentCategories", listOfParentCategories);
return "add-subcategory-form";
}
@PostMapping("/add-subcategory")
public String addSubcategory(@Valid @ModelAttribute("category") CategoryDTO categoryDTO, BindingResult bindingResult){

if(bindingResult.hasErrors()){
return "add-subcategory-form";
}
categoryService.add(categoryDTO);
return "redirect:/category/subcategory-form";
}  

在输入字段中,当我输入空白时,验证器会使用控制器中的hasErrors正确地发现它,但当我在发现空白并返回false后返回表单时,它会给出以下信息:

白标签错误页此应用程序没有显式映射/错误,所以您将此视为回退。

11月18日星期三13:45:26 EET 2020出现意外错误(类型=内部服务器错误,状态=500)。期间发生错误模板解析(模板:类路径资源[模板/添加子类别表单.html]")org.thimeleaf.exceptions.TemplateInput异常:发生错误在模板解析期间(模板:"类路径资源"[模板/添加子类别表单.html]")在org.thymelaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplate Parser.java:241)在org.thymelaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplate Parser.java:100)在org.thymelaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)网址:org.thymelaf.TemplateEngine.prrocess(TemplateEngine.java:1098)org.thymelaf.TemplateEngine.process(TemplateEngine.java:1072)org.thymelaf.spring5.view.ThymeleafView.renderFragment(ThymelafView.java:362)在org.thymelaf.spring5.view.ThymeleafView.render(ThymelafView.java:189)在org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373)在org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1118)在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057)在org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)在org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)位于org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)位于org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)在org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)在org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequest filter.java:119)在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)在org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequest filter.java:119)在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)在org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequest filter.java:119)在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)在org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncoding filter.java:201)在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequest filter.java:119)在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)在org.apache.catalina.core.StandardWrapperValv.invoke(StandardWrapperValve.java:202)在org.apache.catalina.core.StandardContextValv.invoke(StandardContextValv.java:97)在org.apache.catalina.authenticator.AuthenticatorBase.ioke(AuthenticatorBase.java:542)在org.apache.catalina.core.StandardHostValv.invoke(StandardHostValve.java:143)在org.apache.catalina.vals.ErrorReportValve.ioke(ErrorReportValve.java:92)在org.apache.catalina.core.StandardEngineValv.invoke(StandardEngineValv.java:78)在org.apache.catalina.connecter.CoyoteAdapter.service(Coyotedapter.java:343)在org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)在org.apache.coyote.AbstractProcessorLight.prrocess(AbstractProcessorLight.java:65)在org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)在org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)在org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)在java.base/java.util.concurrent.ThreadPoolExecutior.runWorker(ThreadPoolExecutior.java:1128)在java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)在org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)在java.base/java.lang.Thread.run(Thread.java:834)中,由以下原因引起:org.attoparser.ParseException:评估SpringEL时出现异常表达式:";parentCategories.size()==0"(模板:"添加子类别形式"-第13行,第10列)org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)org.attoparser.MarkupParser.parse(MarkupParser.java:257)org.thymelaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplate Parser.java:230)…52更多原因:org.thmeleaf.exceptions.TemplateProcessingException:异常评估SpringEL表达式:";parentCategories.size()==0"(模板:"添加子类别形式"-第13行,第10列)org.thymelaf.spring5.expression.SPELVariableExpressionEvaluator.eevaluate(SPELVariableExpression Evaluator.java:290)在org.thymelaf.standard.expression.VariableExpression.executeVariableExpression(VariableExpression.java:166)在org.thymelaf.standard.expression.SimpleExpression.executeSimple(SimpleExpression.java:66)在org.thymelaf.standard.expression.expression.execute(expression.java:109)在org.thymelaf.standard.expression.expression.execute(expression.java:138)在org.thymelaf.standard.expression.expression.execute(expression.java:125)在org.thymelaf.standard.processor.StandardIfTagProcessor.isVisible(StandardIfTagProcesser.java:59)在org.thymelaf.standard.processor.AbstractStandardConditionalVisibilityTagProcessor.doProcess(AbstractStandardConditionVisibilitytagProcessor.java:61)在org.thymelaf.processer.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcess.java:74)在org.thymelaf.processor.element.AbstractElementTagProcessor.procedure(AbstractElementTagProcesser.java:95)在org.thymelaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)在org.thymelaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314)在org.thymelaf.engine.TemplateHandlerAdapterMarkupHandler.handleOpenElementEnd(TemplateHandlerAdapter MarkupHandler.java:304)在org.thymelaf.templatesepser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleOpenElementEnd(InlinedOutputExpression MarkupHandler.java:278)在org.thymelaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleOpenElementEnd(OutputExpressionInlinePreProcessorHandler.java:186)在org.thymelaf.templatesepser.markup.InlinedOutputExpressionMarkupHandler.handleOpenElementEnd(InlinedOutputExpression MarkupHandler.java:124)在org.attoparser.HtmlElement.handleOpenElementEnd(HtmlElement.java:109)在org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297)在org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402)在org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159)网址:org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710)org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)。。。54更多原因:org.springframework.expression.spec.SpelEvaluation异常:EL1011E:方法调用:试图对null上下文对象调用方法size()在org.springframework.expression.spel.ast.MethodReference.sthrowIfNotNullSafe(MethodReference.java:154)在org.springframework.expression.spel.ast.MethodReference.getValueRef(MethodReference.java:83)在org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:70)在org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91)在org.springframework.expression.spel.ast.OpEQ.getValueInternal(OpEQ.java:42)在org.springframework.expression.spel.ast.OpEQ.getValueInternal(OpEQ.java:32)在org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:112)在org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:337)在org.thymelaf.spring5.expression.SPELVariableExpressionEvaluator.eevaluate(SPELVariableExpression Evaluator.java:263)…还有75个

问题是,对于我的另一种形式,我只需要添加父类别,如果我添加一个空白,它会返回thymelaf并打印我写的错误消息,但我无法为这种形式解决这个问题。

堆栈跟踪对该问题有以下提示:

评估SpringEL表达式时出现异常:";parentCategories.size()==0"(模板:"添加子类别形式"-第13行,第10列)

和:

试图在上对null上下文对象调用方法size()

这意味着parentCategories不再存在于Thymelaf上下文中。

当出现错误时,您需要再次在模型中重新添加parentCategories

@PostMapping("/add-subcategory")
public String addSubcategory(@Valid @ModelAttribute("category") CategoryDTO categoryDTO, BindingResult bindingResult) {

if(bindingResult.hasErrors()){
List<CategoryDTO> listOfParentCategories = categoryService.getParentCategories();
model.addAttribute("parentCategories", listOfParentCategories);
return "add-subcategory-form";
}
categoryService.add(categoryDTO);
return "redirect:/category/subcategory-form";
}  

最新更新