Thymeleaf返回一个String数组而不是List <object>

时间:2018-06-25 13:38:53

标签: java spring thymeleaf

我正在学习如何使用Spring Boot和Thymeleaf。我有一个问题,我在表单列表中向Thymeleaf页面提供了特定对象的列表。当用户选择值并发布结果时,结果是所选对象的字符串,并且与我要在其中存储值的对象不兼容。

这听起来像是一纸空话,下面是代码。

我的问题是:是否仍然可以确保Thymeleaf返回对象列表?

输入:一个类将一堆配料传递给表单 此类将“成分”类的“列表”传递给表单(此过滤无关紧要-插入一个列表作为model属性的值,键是成分的类型)

@GetMapping
public String showDesignForm(Model model) {
    List<Ingredient> ingredients = new ArrayList<>();
    ingredientRepo.findAll().forEach(i -> ingredients.add(i));  
    Type[] types = Ingredient.Type.values();
    for (Type type : types) {
        model.addAttribute(type.toString().toLowerCase(), filterByType (ingredients, type));
    }   
    model.addAttribute("taco", new Taco()); 
    return "design";
}

Thymeleaf获取该列表并将其显示在复选框中

<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="@{/styles.css}" />
</head>
<body>
<h1>Design your taco!</h1>
<img th:src="@{/images/TacoCloud.png}"/>
<form method="POST" th:object="${taco}">
<div class="grid">
<div class="ingredient-group">
<h3>Designate your wrap:</h3>
<div th:each="ingredient : ${wrap}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group">
<h3>Pick your protein:</h3>
<div th:each="ingredient : ${protein}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group">
<h3>Choose your cheese:</h3>
<div th:each="ingredient : ${cheese}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group">
<h3>Determine your veggies:</h3>
<div th:each="ingredient : ${veggies}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group">
<h3>Select your sauce:</h3>
<div th:each="ingredient : ${sauce}">
<input name="ingredients" type="checkbox" th:value="${ingredient}" />
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
</div>
<div>
<h3>Name your taco creation:</h3>
<input type="text" th:field="*{name}"/>
<br/>
<button>Submit your taco</button>
</div>
</form>
</body>
</html>

目标类别:期望返回的值为列表

package tacos;

import java.util.Date;
import java.util.List;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import lombok.Data;

@Data
public class Taco {

    private Long id;

    private Date createdAt;

    @NotNull
    @Size(min=5, message="Name must be at least 5 characters long")
    private String name;
    @Size(min=1, message="You must choose at least 1 ingredient")
    private List<Ingredient> ingredients;
}

错误:

  

对象“ taco”在字段“成分”上的字段错误:拒绝的值[Ingredient(id = FLTO,name = Flour Tortilla,type = WRAP),Ingredient(id = CHED,name = Cheddar,type = CHEESE)] ;代码[typeMismatch.taco.ingredients,typeMismatch.ingredients,typeMismatch.java.util.List,typeMismatch];参数[org.springframework.context.support.DefaultMessageSourceResolvable:代码[taco.ingredients,ingredients];参数[];默认消息[成分]];默认消息[无法将类型'java.lang.String []'的属性值转换为属性'成分'的必需类型'java.util.List';嵌套异常为java.lang.IllegalStateException:无法将属性“ ingredients [0]”的类型“ java.lang.String”的值转换为所需的类型“ tacos.Ingredient”:找不到匹配的编辑器或转换策略]

3 个答案:

答案 0 :(得分:1)

我看过一个视频,该视频帮助在Thymeleaf页面的String结果和Spring中的POST方法之间创建了一个转换器。

sparse matrix

答案 1 :(得分:1)

我在某些代码中遇到了相同的问题,但是我通过使用Spring JPA克服了它。但是,如果您使用的不是Spring JPA,则可以将此转换器用于您的应用程序。根据您的代码,Ingredient的属性ID为String。这样的代码将。

@Component
public class IngredientConverter implements Converter<String, Ingredient> {

private final IngredientRepo ingredientRepo;

@Autowired
public IngredientConverter(IngredientRepo ingredientRepo) {

    this.ingredientRepo = ingredientRepo;
}

@Override
public Ingredient convert(String source) {

      List<Ingredient> ingredients = new ArrayList<>();

      ingredientRepo.findAll().forEach(i -> ingredients.add(i));

      for (Ingredient ingredient : ingredients) {

        // You may use equal() method
        if (ingredient.getId() == source)

            return ingredient;
      }

      return null;
   }

}

答案 2 :(得分:0)

您应将private List<Ingredient> ingredients;更改为private List<String> ingredients;