【发布时间】:2018-07-29 09:00:37
【问题描述】:
我是 Thymeleaf 的新手,遇到了一个奇怪的问题。让我先告诉你什么是有效的。我有两个简单的类
public class Country {
private long countryid;
private String name;
}
和
public class Person {
private String name;
private long countryId;
}
在 addPerson 页面中,我想从下拉列表中选择国家。我手动创建了一个国家列表(来自 spring 控制器),然后我的 addPerson.html 设计为
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Add Person</h1>
<form action="#" th:action="@{/addPerson}" th:object="${person}"
method="POST">
<p>
Name: <input type="text" th:field="*{name}" />
</p>
<select th:field="*{countryId}" class="form-control">
<option th:each="country: ${countryList}"
th:value="${country.countryid}" th:text="${country.name}"></option>
</select>
<p>
<input type="submit" value="Submit" /> <input type="reset"
value="Reset" />
</p>
</form>
</body>
</html>
当我从下拉列表中选择一个国家时,我得到了 countryid,一切正常。 现在我想改变我的 Person 类如下
public class Person {
private String name;
private Country country;
}
所以,我想要的是 country 对象本身,而不是 countryid。保持其他一切不变,我已将 addPerson.html 更改为
<select th:field="*{country}" class="form-control">
<option th:each="country: ${countryList}"
th:value="${country}" th:text="${country.name}"></option>
</select>
现在我可以看到下拉列表,但在提交时出现错误
出现意外错误(类型=错误请求,状态=400)。 object='person' 的验证失败。错误计数:1
简而言之:它适用于对象的属性,我需要做什么来处理整个对象本身?
请帮助。
更新 1:控制器方法签名
@GetMapping("/addPerson")
public String addPerson(Model model) {
Country country1 = new Country();
country1.setCountryid(1);
country1.setName("A");
Country country2 = new Country();
country2.setCountryid(2);
country2.setName("B");
List<Country> countryList = new ArrayList<Country>();
countryList.add(country1);
countryList.add(country1);
model.addAttribute("countryList", countryList);
model.addAttribute("person", new Person());
return "addPerson";
}
@PostMapping("/addPerson")
public void processAddPerson(@Valid @ModelAttribute("person") Person person) {
System.out.println(person.getName());
}
更新 2
经过调试,我发现第二种情况,在提交时,控件根本不会转到Person类的setCountry方法!
【问题讨论】:
-
添加控制器方法签名。
-
@Alien:已更新。请检查。
-
这只是一种解决方法,但在我的选择中,我们不需要在每个用例中都使用绑定。不要使用 th:field="*{country}" 属性。保持简单,1.) 使用 name="countryId",2.) 在 processAddPerson-method 中接收 countryId 作为额外参数,3.) 在方法中手动将 country-object “连接”到 person-object .绑定是创建的,但有时不值得不惜一切代价去做。
-
@Flocke:嗨,Flocke,非常感谢您的回复。我的实际用例有所不同,可以在这篇文章中找到 - stackoverflow.com/questions/51571933/… 。我缩小了当前帖子中的问题范围。如您所见,我确实需要选定的对象。为什么 setter 方法没有被调用真是令人惊讶!如果您有任何想法,请分享。
-
@user3274247:这不是百里香叶特有的麻烦。我从 spring-binding 和 jsp 中知道这一点,所谓的解决方案是定义自己的格式化程序(这就是你必须做的)。您生成的选项代码类似于 。那不是国家对象,而是字符串。因此,您需要一个 Formatter 来从该输入 ([1, UK]) 创建一个 Country-object 并在 Person-class 中进行注释。
标签: java spring-mvc spring-boot thymeleaf