【问题标题】:thymeleaf Failed to convert property value of type java.lang.String to required type java.util.Listthymeleaf 无法将 java.lang.String 类型的属性值转换为所需的 java.util.List 类型
【发布时间】:2019-03-11 00:58:29
【问题描述】:

我是 Spring 和 Spring Boot 的新手,并且正在阅读一本充满缺失信息的书。

我有一个墨西哥卷饼课:

public class Taco {

    ...

    @Size(min=1, message="You must choose at least 1 ingredient")
    private List<Ingredient> ingredients;

    ...
}

如您所见,ingredientsList&lt;Ingredient&gt; 类型,这就是问题所在,它曾经是 List&lt;String&gt; 类型,但那是在我开始在数据库中保存数据之前,现在它必须是 List&lt;Ingredient&gt;这破坏了整个事情。

在控制器中,我有以下内容(除其他外,我认为这是解决手头问题所需的唯一代码,但如果您需要更多,请告诉我):

@ModelAttribute
    public void addIngredientsToModel(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));
        }
    }

private List<Ingredient> filterByType(List<Ingredient> ingredients, Type type) {
        return ingredients
                    .stream()
                    .filter(x -> x.getType()
                    .equals(type))
                    .collect(Collectors.toList());
    }

最后在我的百里香文件中我有:

<span class="text-danger" 
                th:if="${#fields.hasErrors('ingredients')}" 
                th:errors="*{ingredients}">
            </span>

导致错误的原因:

thymeleaf Failed to convert property value of type java.lang.String to required type java.util.List

再一次,当private List&lt;Ingredient&gt; ingredients;private List&lt;String&gt; ingredients; 时它可以工作,但现在它必须是private List&lt;Ingredient&gt; ingredients;,因为它在数据库中保存的方式但在这一点上坏了,如何修复它?

【问题讨论】:

  • 您必须在表单中定义 th:object 以便 Thymeleaf 可以识别您的成分对象。
  • 我遇到了类似的错误。从书中获得的代码可能不是没有bug的。

标签: spring-boot thymeleaf


【解决方案1】:

我遇到了同样的问题,我们这里需要一个转换器。

package tacos.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import tacos.Ingredient;
import tacos.data.IngredientRepository;

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

private IngredientRepository ingredientRepo;

@Autowired
public IngredientByIdConverter(IngredientRepository ingredientRepo) {
    this.ingredientRepo = ingredientRepo;
}

@Override
public Ingredient convert(String id) {
    return ingredientRepo.findOne(id);
}

}

【讨论】:

  • 绑定发生时应该如何调用?
【解决方案2】:

对上面伊恩回答的优化:

在转换器的构造函数中获取成分。

package com.joeseff.xlabs.chtp01_1.tacos.converter;

import com.joeseff.xlabs.chtp01_1.tacos.model.Ingredient;
import com.joeseff.xlabs.chtp01_1.tacos.respository.jdbc.IngredientRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author - JoeSeff
 * @created - 23/09/2020 13:41
 */
@Component
public class IngredientConverter implements Converter<String, Ingredient> {
    private final IngredientRepository ingredientRepo;
    private final List<Ingredient> ingredients = new ArrayList<>();
    
    @Autowired
    public IngredientConverter(IngredientRepository ingredientRepo) {
        this.ingredientRepo = ingredientRepo;
    
        ingredientRepo.findAll().forEach(ingredients::add);
    }
    
    @Override
    public Ingredient convert(String ingredientId) {
        return ingredients
                .stream().filter( i -> i.getId().equals(ingredientId))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("Ingredient with ID '" + ingredientId + "' not found!"));
    }
}

【讨论】:

    猜你喜欢
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 2021-06-13
    • 1970-01-01
    • 2017-05-12
    • 2018-08-21
    • 2017-04-21
    相关资源
    最近更新 更多