我试图更改此示例thymeleafexamples-stsm的代码,因此我更改了类类型的枚举类型:
Type.java
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;
}
seedstartermng.html
<select th:field="*{type}">
<option th:each="type : ${allTypes}" th:value="${type}" th:text="${type.type}">Wireframe</option>
</select>
所以,我不能添加Seed Starter。
我的输出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类型的属性值转换为必需值 输入属性类型的thymeleafexamples.stsm.business.entities.Type; 嵌套异常是java.lang.IllegalStateException:无法转换 类型[java.lang.String]的值为必需的类型 [thymeleafexamples.stsm.business.entities.Type]属性类型:否 找到匹配的编辑器或转换策略
如何映射到正确键入?我希望你能帮助我。谢谢。
答案 0 :(得分:13)
我知道这个问题已经过时了,但是答案可能对某些人有帮助,因为我无法轻易找到它。
要解决此问题,Thymeleaf使用Formatters在Object和String之间进行转换。
在提交阶段(POST),Formatter Service将转换String 回到
对象。
首先为要在标记中使用的Class实现Formatter服务:
@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
}
}
这是一个非常简单的类,有两种方法:
现在,我们要告诉Spring-Thymeleaf abbout我们的格式化程序,或者我们可以称之为转换器。为此,我们在WebConfig中注册了这个格式化程序(Configuration class,它扩展了WebMvcConfigurerAdapter):
@Configuration
@EnableWebMvc
@ComponentScan(value = { "your package" })
public class WebConfig extends WebMvcConfigurerAdapter {
....
//Formatters
@Autowired //Without autowire, this solution may not work
private TypeFormatter typeFormatter;
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(typeFormatter);
}
}
现在我们的解决方案已准备好在html文件中实现,但如何告诉Thymeleaf应用转换? 答案是使用 th:field =&#34; * {type}&#34; 属性并使用双括号语法 th:value =&#34; $ {{type} }&#34; 强>:
<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>
最后要说的是,有时我们想在下拉列表中添加一个标题,例如&#34; -----选择类型-----&#34;为了防止默认选择以及向用户解释。在这种情况下,您必须设置 th:value =&#34; NULL&#34; ,除非您收到转换错误。
答案 1 :(得分:12)
该错误消息基本上表示Spring不知道如何将字符串thymeleafexamples.stsm.business.entities.Type@2c08cec0
转换为Type的实例。这是您的代码中的错误,因为尝试这样做没有任何意义。
您不应该使用Object的toString()
值作为表单下拉标识符。您需要(代码)更好的策略来识别用户选择的类型。
常用方法是使用id
属性:
<option th:each="type : ${allTypes}" th:value="${type.id}" th:text="${type.type}">Wireframe</option>
提交表单后,您需要根据控制器上的ID名称退出Type的实例