选择带有对象的标记-Thymeleaf和Spring MVC
我试图更改此示例的代码,因此我更改了类类型的枚举类型: Type.java选择带有对象的标记-Thymeleaf和Spring MVC,spring,spring-mvc,thymeleaf,Spring,Spring Mvc,Thymeleaf,我试图更改此示例的代码,因此我更改了类类型的枚举类型: Type.java public class Type { private Integer id; private String type; ...getters and setters } SeedStarterMngController.java @ModelAttribute("allTypes") public List<Type> populateTypes() {
public class Type {
private Integer id;
private String type;
...getters and setters
}
SeedStarterMngController.java
@ModelAttribute("allTypes")
public List<Type> populateTypes() {
Type type1 = new Type();
type1.setId(1);
type1.setType("OUTDOOR");
Type type2 = new Type();
type2.setId(2);
type2.setType("INDOOR");
List<Type> tipos = new ArrayList<Type>();
tipos.add(type1);
tipos.add(type2);
return tipos;
}
@modeldattribute(“所有类型”)
公共列表populateTypes(){
类型1=新类型();
类型1.setId(1);
类型1.设置类型(“室外”);
类型2=新类型();
类型2.setId(2);
类型2.设置类型(“室内”);
List tipos=new ArrayList();
附加提示(类型1);
附加提示(类型2);
返回tipos;
}
seedstartermng.html
<select th:field="*{type}">
<option th:each="type : ${allTypes}" th:value="${type}" th:text="${type.type}">Wireframe</option>
</select>
线框
所以,我不能添加种子发酵剂
我的输出html是
<select id="type" name="type">
<option value="thymeleafexamples.stsm.business.entities.Type@2c08cec0">OUTDOOR</option>
<option value="thymeleafexamples.stsm.business.entities.Type@26cf024">INDOOR</option>
</select>
户外的
室内的
错误是
无法将java.lang.String类型的属性值转换为必需的
属性类型的类型为examples.stsm.business.entities.type;
嵌套异常为java.lang.IllegalStateException:无法转换
将[java.lang.String]类型的值转换为所需类型
[Examples.stsm.business.entities.Type]属性类型:否
找到匹配的编辑器或转换策略
如何正确映射到类型?我希望你能帮助我。多谢各位 该错误消息基本上是说Spring不知道如何转换字符串
thymeleafexamples.stsm.business.entities。Type@2c08cec0
导入类型的实例。这是代码中的一个bug,因为这样做没有任何意义
您不应该使用对象的toString()
值作为表单下拉标识符。您需要有一个(更好的)代码策略来识别用户选择的类型
常用的方法是使用id
属性:
<option th:each="type : ${allTypes}" th:value="${type.id}" th:text="${type.type}">Wireframe</option>
线框
提交表单后,您需要根据控制器上的id名称注销类型实例我知道这个问题很老,但下面的答案可能会对某些人有所帮助,因为我无法轻松找到它 为了解决这个问题,Thymeleaf使用格式化程序在对象和字符串之间进行转换
- 在显示阶段(GET),格式化程序服务将对象转换为 绳子李>
- 在提交阶段(POST),格式化程序服务将转换字符串 回到 反对
@Service
public class TypeFormatter implements Formatter<Type> {
@Autowired
TypeService typeService;//Service -> DB
@Override
public String print(Type object, Locale locale) {
return (object != null ? object.getId().toString() : "");
}
@Override
public Type parse(String text, Locale locale) throws ParseException {
Integer id = Integer.valueOf(text);
return this.typeService.get(id);//return Type object form DB
}
}
现在我们的解决方案可以在html文件中实现了,但是如何告诉Thymeleaf应用转换呢?
答案是使用th:field=“*{type}”属性和双括号语法th:value=“${type}”:
<select th:field="*{type}">
<option th:value="NULL" th:text="---Select Type---"></option>
<option th:each="type : ${allTypes}" th:value="${{type}}" th:text="${type.type}">Wireframe</option>
</select>
线框
- th:field=“*{type}”默认情况下正在应用已注册的格式化程序服务。它会将类型转换为字符串(这里的字符串是类型Id)
- th:value=“${{type}}”也在将类型转换为字符串
- 在submit中,Spring将使用格式化程序服务将Id转换回来 反对
最后要说的是,有时我们想在下拉列表中添加一个标题,如“----选择类型------”,以防止默认选择,并向用户解释。在这种情况下,必须设置th:value=“NULL”,除非出现转换错误。在th:value中添加ID,这将向浏览器公开该值。我尽量不显示任何身份证。这就是为什么我在控制器中使用“@SessionAttributes”和“@InitBinder”。然后做任何你需要的事情,这样你就可以将某种字符串标识符传递到下拉列表中,并在发布表单时将其取回。字符串
emplieafexamples.stsm.business.entities。Type@2c08cec0
将永远不会成为java对象。时期考虑java枚举、序列化、使用另一个非敏感标识符等。希望遵循您的指令,但我无法找到Type Service类。你能告诉我它在哪个罐子里吗?谢谢。解决了,这只是一个刀类,需要自己实现。
<select th:field="*{type}">
<option th:value="NULL" th:text="---Select Type---"></option>
<option th:each="type : ${allTypes}" th:value="${{type}}" th:text="${type.type}">Wireframe</option>
</select>