Cannot convert value of type 'java.lang.String'

138
31 мая 2019, 02:30

Читаю Spring in action 5, пытаюсь реализовать примеры. На одном из контроллеров выходит ошибка:

Field error in object 'pizza' on field 'ingredients': rejected value [PFDG,CHED,KTCH]; codes [typeMismatch.pizza.ingredients,typeMismatch.ingredients,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [pizza.ingredients,ingredients]; arguments []; default message [ingredients]]; default message [Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.List' for property 'ingredients'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.spring5inaction.pizzacloud.entity.Ingredient' for property 'ingredients[0]': no matching editors or conversion strategy found]]

Только осваиваю Spring, просьба подсказать в чем проблема и по возможности как ее решить?

Код контроллера:

@Controller
@RequestMapping("/design")
@SessionAttributes("order")
public class DesignPizzaController {
private final IngredientRepository repository;
private final PizzaRepository pizzaRepository;
@Autowired
public DesignPizzaController(IngredientRepository repository, PizzaRepository pizzaRepository) {
    this.repository = repository;
    this.pizzaRepository = pizzaRepository;
}
@ModelAttribute(name = "order")
public Order order(){return new Order();}
@ModelAttribute(name = "pizza")
public Pizza pizza(){return new Pizza();}
@GetMapping
public String showDesignForm(Model model){
    List<Ingredient> ingredients = new ArrayList<Ingredient>();
    repository.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("design", new Pizza());
    return "design";
}

//Make some errors with valid entity
@PostMapping
public String processDesign(Pizza pizza, @RequestParam("ingredients") String[] strs, @ModelAttribute Order order){
//    List<Ingredient> ingredients = new ArrayList<>();
//        for (String str : strs) {
//            System.out.println(str);
//            ingredients.add(repository.findOne(str));
//        }
//        pizza.setIngredients(ingredients);
    System.out.println(pizza);
//        Pizza saved = pizzaRepository.save(pizza);
//        order().addDesign(saved);
    return "redirect:/orders/current";
}
private List<Ingredient> filterByType(
        List<Ingredient> ingredients, Type type) {
    return ingredients
            .stream()
            .filter(x -> x.getType().equals(type))
            .collect(Collectors.toList());
}

}

Код вьюшки:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" th:href="@{/styles.css}" />
<title>Pizza cloud</title>
</head>
<body>
<h1>Design your pizza:</h1>
<img th:src="@{/images/pizza.png}" width="275" height="255">
<form method="post" th:object="${pizza}">
    <span class="validationError"
          th:if="${#fields.hasErrors('ingredients')}"
          th:errors="*{ingredients}">Ingredient Error</span>
<div class="grid">
<div class="ingredient-group" id="doughs">
    <h3>Designate your dough:</h3>
    <div th:each="ingredient: ${dough}">
        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
        <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    </div>
</div>
<div class="ingredient-group" id="meats">
    <h3>Choose your meat:</h3>
    <div th:each="ingredient : ${meat}">
        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
        <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    </div>
</div>
<div class="ingredient-group" id="cheeses">
    <h3>Choose your cheese:</h3>
    <div th:each="ingredient : ${cheese}">
        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
        <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    </div>
</div>
<div class="ingredient-group" id="veggies">
    <h3>Determine your veggies:</h3>
    <div th:each="ingredient : ${veggies}">
        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"
        />
        <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    </div>
</div>
<div class="ingredient-group" id="sauces">
    <h3>Select your sauce:</h3>
    <div th:each="ingredient : ${sauce}">
        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"
        />
        <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    </div>
</div>
</div>
    <h3>Name your pizza creation:</h3>
    <input type="text" th:field="*{name}"/>
    <span th:text="${#fields.hasErrors('name')}">XXX</span>
    <span class="validationError"
          th:if="${#fields.hasErrors('name')}"
          th:errors="*{name}">Name Error</span>
    <br/>
    <button>Submit your pizza</button>
</form>

Сам класс:

public class Pizza {
private Long id;
private Date createdAt;
private String name;
private List<Ingredient> ingredients;
public Pizza() {
}
public Pizza(String name, List<Ingredient> ingredients) {
    this.name = name;
    this.ingredients = ingredients;
}

public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}
public Date getCreatedAt() {
    return createdAt;
}
public void setCreatedAt(Date createdAt) {
    this.createdAt = createdAt;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public List<Ingredient> getIngredients() {
    return ingredients;
}
public void setIngredients(List<Ingredient> ingredients) {
    this.ingredients = ingredients;
}
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Pizza pizza = (Pizza) o;
    return Objects.equals(id, pizza.id) &&
            Objects.equals(createdAt, pizza.createdAt) &&
            Objects.equals(name, pizza.name) &&
            Objects.equals(ingredients, pizza.ingredients);
}
@Override
public int hashCode() {
    return Objects.hash(id, createdAt, name, ingredients);
}
@Override
public String toString() {
    return "Pizza{" +
            "id=" + id +
            ", createdAt=" + createdAt +
            ", name='" + name + '\'' +
            ", ingredients=" + ingredients +
            '}';
}
}
Answer 1
[Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.List' for property 'ingredients';

Вы передаёте массив стрингов там, где требуется List.

READ ALSO
unexpected token, identifier expected

unexpected token, identifier expected

Что я пропустил в коде?

113
Получить значение из DatePicker

Получить значение из DatePicker

Используется JavaFx для создания интерфейсаВ окне есть элемент DatePicker

112
Как из Uikit2 оставить только стили сетки

Как из Uikit2 оставить только стили сетки

Столкнулся с такой проблемой, что надо оптимизировать проект с данным фреймворкомПолная библиотека занимает > 100kБ (И это без компонентов)...

131
Как сделать чтобы в grid отсчет шел со второго ряда?

Как сделать чтобы в grid отсчет шел со второго ряда?

Как сделать так что б последующие элементы не лезли в пространство grid-column: 1 / 3Можно ли это реализовать без добавления сторонних тегов в верстку,...

149