Читаю 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 +
'}';
}
}
[Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.List' for property 'ingredients';
Вы передаёте массив стрингов там, где требуется List.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Используется JavaFx для создания интерфейсаВ окне есть элемент DatePicker
Столкнулся с такой проблемой, что надо оптимизировать проект с данным фреймворкомПолная библиотека занимает > 100kБ (И это без компонентов)...
Как сделать так что б последующие элементы не лезли в пространство grid-column: 1 / 3Можно ли это реализовать без добавления сторонних тегов в верстку,...