Я учу весну из 5-го издания Sping in Action Крэйга Уоллса. Я искал в inte rnet проблему, но не нашел решения.
Проблема:
design.html
имеет форму со списком, который отображается пустым, если поля формы имеют ошибку проверки. Ниже приведен код:
дизайн. html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>Customize your Taco!</h1>
<img th:src="@{/images/TacoCloud.png}" />
<form method="POST" th:object="${design}">
<div class="grid">
<div class="ingredient-group" id="wraps">
<h3>Designate your wrap:</h3>
<div th:each="ingredient : ${wrap}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}" /> <span th:text="${ingredient.name}">INGREDIENT</span><br />
</div>
</div>
<div class="ingredient-group" id="proteins">
<h3>Pick your protein:</h3>
<div th:each="ingredient : ${protein}">
<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>
<div>
<h3>Name your taco creation:</h3>
<input type="text" th:field="*{name}" />
<span class="validationError" th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</span> <br />
<input type="submit" value="Submit" />
</div>
</form>
</body>
</html>
DesignTacoController
package tacos.web;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.slf4j.Slf4j;
import tacos.Ingredient;
import tacos.Ingredient.Type;
import tacos.Taco;
@Slf4j
@Controller
@RequestMapping("/design")
public class DesignTacoController {
@GetMapping
public String showDesignForm(Model model) {
List<Ingredient> ingredients = new ArrayList<>();
ingredients.add(new Ingredient("FLTO", "Flour Tortilla", Type.WRAP));
ingredients.add(new Ingredient("COTO", "Corn Tortilla", Type.WRAP));
ingredients.add(new Ingredient("GRBF", "Ground Beef", Type.PROTEIN));
ingredients.add(new Ingredient("CARN", "Carnitas", Type.PROTEIN));
ingredients.add(new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES));
ingredients.add(new Ingredient("LETC", "Lettuce", Type.VEGGIES));
ingredients.add(new Ingredient("CHED", "Cheddar", Type.CHEESE));
ingredients.add(new Ingredient("JACK", "Monterrey Jack", Type.CHEESE));
ingredients.add(new Ingredient("SLSA", "Salsa", Type.SAUCE));
ingredients.add(new Ingredient("SRCR", "Sour Cream", Type.SAUCE));
Type[] types=Ingredient.Type.values();
for(Type type: types) {
model.addAttribute(type.toString().toLowerCase(), filterByType(ingredients, type));
}
model.addAttribute("design", new Taco());
return "design";
}
@PostMapping
public String processDesign(@Valid @ModelAttribute("design") Taco design, Errors errors) {
if(errors.hasErrors()) {
return "design";
}
log.info("Processing Design: " + design);
return "redirect:/orders/current";
}
private List<Ingredient> filterByType(List<Ingredient> ingredients, Type type) {
return ingredients.parallelStream().filter(i->i.getType().equals(type)).collect(Collectors.toList());
}
}
Taco. java
package tacos;
import lombok.Data;
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Data
public class Taco {
@NotNull
@Size(min=5, message="Name must be atleast 5 characters long.")
private String name;
@Size(min=1, message="You must choose atleat 1 ingredient.")
private List<String> ingredients;
}
дизайн. html рендеринг по умолчанию
дизайн. html после ошибки проверки - Почему список пуст? Как я могу отобразить список как раньше?