Java 如何使用Thymeleaf下拉列表中的对象
我是新来的百里香,遇到了一个奇怪的问题。让我先告诉你什么有效。我有两个简单的班Java 如何使用Thymeleaf下拉列表中的对象,java,spring-mvc,spring-boot,thymeleaf,Java,Spring Mvc,Spring Boot,Thymeleaf,我是新来的百里香,遇到了一个奇怪的问题。让我先告诉你什么有效。我有两个简单的班 public class Country { private long countryid; private String name; } 及 在addPerson页面中,我想从下拉列表中选择国家。我已经手动创建了一个国家列表(来自SpringController),然后我的addPerson.html被设计为 <!DOCTYPE HTML> <html xmlns:th="h
public class Country {
private long countryid;
private String name;
}
及
在addPerson页面中,我想从下拉列表中选择国家。我已经手动创建了一个国家列表(来自SpringController),然后我的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>
因此,我希望使用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());
}
@GetMapping(“/addPerson”)
公共字符串addPerson(模型){
Country Country 1=新国家();
country1.setCountryid(1);
国家1.设定名称(“A”);
Country Country 2=新国家();
country2.setCountryid(2);
国家2.设定名称(“B”);
List countryList=new ArrayList();
countryList.add(country1);
countryList.add(country1);
model.addAttribute(“countryList”,countryList);
model.addAttribute(“person”,newperson());
返回“addPerson”;
}
@邮戳(“/addPerson”)
public void processAddPerson(@Valid@modeldattribute(“person”)person){
System.out.println(person.getName());
}
更新2
调试后,我发现在第二种情况下,在提交时,控件根本不会进入Person类的
setCountry
方法 将BindingResult对象添加到方法中
public String processAddPerson( @Valid Person person,BindingResult bindingResult,Model model)
确保
BindingResult
必须紧跟在用@Valid
添加控制器方法签名注释的对象之后。@Alien:已更新。请检查。这只是一个解决方法,但在我的选择中,我们不需要在每个用例中使用绑定。不要使用th:field=“*{country}”属性。保持简单,1.)使用name=“countryId”,2.)在processAddPerson方法中将countryId作为额外参数接收,3.)在方法中将country对象手动“连接”到person对象。装订是创造出来的,但有时不值得不惜一切代价去做。@Flooke:你好,Flooke,非常感谢你的回复。我的实际用例是不同的,可以在这篇文章中找到。在当前的帖子中,我缩小了问题的范围。如您所见,我确实需要选定的对象。为什么setter方法没有被调用,这真是令人惊讶!如果您有任何想法,请与我们分享。@user3274247:这不是什么特别的麻烦。我从spring绑定和jsp中了解到这一点,所谓的解决方案是定义自己的格式化程序(这是您必须做的)。您生成的选项代码看起来像英国。这不是一个国家的对象,它是一个字符串。因此,您需要一个格式化程序,该格式化程序根据该输入([1,UK])创建一个Country对象,并在Person-class.Hi-Alien中进行注释,谢谢您的回答。但在控制器中,country
字段仍然为空。所以下拉选择不起作用。你能帮个忙吗?试着把name=“person”放在thymeleaf选择标记中并检查。没有成功:(我也试过name=“country”/id=“country”,没有用!就像主线程中提到的:你需要定义一个cosumer格式化程序。
@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());
}
public String processAddPerson( @Valid Person person,BindingResult bindingResult,Model model)