我发现了一些与此相关的线程,但大多数错误似乎来自不正确的命名,但我相信我通过使用@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(如果还没有)。这些似乎是丢失验证消息的两个最常见的原因,所以我想知道我做错了什么。
答案 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
}
}