Thymeleaf不会呈现验证消息

时间:2016-09-17 19:06:04

标签: java spring thymeleaf

我发现了一些与此相关的线程,但大多数错误似乎来自不正确的命名,但我相信我通过使用@ModelAttribute正确地做到了这一点。除了信息显示之外,验证被识别并且一切正常。

这是我的控制器:

         @GetMapping("/search")
            public String searchPage(Model model, @ModelAttribute("searchFormBacking") SearchParamModel search) {
                if (!model.containsAttribute("searchFormBacking")) {
                    model.addAttribute("searchFormBacking", new SearchParamModel());
                } else {
                    model.addAttribute("searchFormBacking", search);
                }
                return "search";
            }

            @PostMapping("/results")
            @SuppressWarnings("unchecked")
            public String resultSubmit(@ModelAttribute("searchFormBacking") @Valid SearchParamModel search, BindingResult result, final RedirectAttributes redirectAttributes) throws Exception{

                if (result.hasErrors()) {
                    //flash errors bound to "searchFormBacking"
                    redirectAttributes.addFlashAttribute("searchFormBacking",search);
                    redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.searchFormBacking",result);
                    return "redirect:/search";
                }

                List<Object[]> queryList = GlobalMethods.baseQuery();

                //input into model&view
                List<CrimeModel> crimeList = GlobalMethods.analyzeQuery(search.getSearchAddress(),search.getSearchDistance(),search.getSearchTime(), queryList);
                List<CrimeRank> rankedList = GlobalMethods.distinctAsList(GlobalMethods.rankedMap(GlobalMethods.distinctCountMap(crimeList)));

                redirectAttributes.addFlashAttribute("searchFormBacking",search);
                redirectAttributes.addFlashAttribute("crimeModel", crimeList);
                redirectAttributes.addFlashAttribute("rankedModel", rankedList);


                return "redirect:/results";

            }

以下是表格:

        <!doctype html>
        <html lang="en" xmlns:th="http://www.thymeleaf.org">
        <head>
            <meta charset="UTF-8"/>
            <meta name="viewport"
                  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
            <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
            <title>Crime Tracker | Search</title>
        </head>
        <body>
        <form th:action="@{/results}" th:object="${searchFormBacking}" method="post">

            <input type="text" th:field="*{searchAddress}" placeholder="Enter address."/>
            <div class="error-message" th:if="${#fields.hasErrors('searchAddress')}" th:errors="*{searchAddress}"></div>
            <br/>

            <input type="text" th:field="*{searchDistance}" placeholder="Enter the distance to search."/>
            <div class="error-message" th:if="${#fields.hasErrors('searchDistance')}" th:errors="*{searchDistance}"></div>
            <br/>

            <input type="text" th:field="*{searchTime}" placeholder="Time-span."/>
            <div class="error-message" th:if="${#fields.hasErrors('searchTime')}" th:errors="*{searchTime}"></div>
            <br/>

            <input type="submit" value="Submit"/>
            <br/>
            <input type="reset" value="Reset"/>
        </form>
        </body>
        </html>

最后是表格支持类:

            public class SearchParamModel {

            @NotNull
            @Size(min = 6, max = 40)
            private String searchAddress;

            @NotNull
            private String searchDistance;

            @NotNull
            private String searchTime;


            public String getSearchAddress() {
                return searchAddress;
            }

            public void setSearchAddress(String searchAddress) {
                this.searchAddress = searchAddress;
            }

            public String getSearchDistance() {
                return searchDistance;
            }

            public void setSearchDistance(String searchDistance) {
                this.searchDistance = searchDistance;
            }

            public String getSearchTime() {
                return searchTime;
            }

            public void setSearchTime(String searchTime) {
                this.searchTime = searchTime;
            }

            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;

                SearchParamModel that = (SearchParamModel) o;

                if (searchAddress != null ? !searchAddress.equals(that.searchAddress) : that.searchAddress != null)
                    return false;
                if (searchDistance != null ? !searchDistance.equals(that.searchDistance) : that.searchDistance != null)
                    return false;
                return searchTime != null ? searchTime.equals(that.searchTime) : that.searchTime == null;

            }

            @Override
            public int hashCode() {
                int result = searchAddress != null ? searchAddress.hashCode() : 0;
                result = 31 * result + (searchDistance != null ? searchDistance.hashCode() : 0);
                result = 31 * result + (searchTime != null ? searchTime.hashCode() : 0);
                return result;
            }
        }

人们似乎遇到的主要错误是,当他们不使用@ModelAttribute时,默认名称就变成了searchParamModel。另外,我已经处理了/ search get映射上的重定向,只创建了一个新的SearchParamModel(如果还没有)。这些似乎是丢失验证消息的两个最常见的原因,所以我想知道我做错了什么。

2 个答案:

答案 0 :(得分:0)

Passing BindingResult through RedirectionAttributes

经过大量的搜索后,我找到了这个线程并在底部附近使用了解决方法,在那里覆盖了flashAttribute,并在GET方法中手动将绑定结果放入模型中。我仍然不知道为什么没有这样做不会有效。此外,@ NotNull注释不会捕获错误,但使用@NotEmpty工作正常。我唯一的猜测是,这些模糊不清的问题是由不同的Spring版本,项目设置等引起的,所以希望如果其他人有这个问题,他们会发现这个链接让我永远找到了。

答案 1 :(得分:0)

添加答案以供将来参考:

问题在于重定向。您正在将页面重定向到search,它将用搜索控制器对象替换所有对象。

修复:我们无需将其重定向到搜索,我们只需在其中呈现搜索模板即可

您可以参考以下答案:https://stackoverflow.com/a/60291568/8591032

您需要像这样更改控制器

@PostMapping("/results")
@SuppressWarnings("unchecked")
public String resultSubmit(@ModelAttribute("searchFormBacking") @Valid SearchParamModel search, BindingResult result, final RedirectAttributes redirectAttributes) throws Exception{

                    if (result.hasErrors()) {
                        return "search"; //changed from redirect:/search
                    }
}