這段在實作controller與view,thymeleaf的view html檔會吃org.springframework.ui.Model的attribute作為變數,在接收到request時,若controller返回的值有對應到src/main/resources/templates的html檔名,就會根據controller傳出來的model來render這個html,html中會有一些th:text等等的語法,就像JSP一樣,會由Thymeleaf處理後,將處理完的html傳給前端瀏覽器。
@Slf4j
@Controller
@RequestMapping("/design")
@SessionAttributes("swordOrder")
public class DesignSwordController {
@ModelAttribute
public void addIngredientsToModel(Model model) {
List<Ingredient> ingredients = Arrays.asList(
new Ingredient("KNIGHT", "knight", Type.BLADE),
new Ingredient("SAMURAI", "samurai", Type.BLADE),
new Ingredient("IRON", "iron", Type.MATERIAL),
new Ingredient("VALYRIAN", "valyrian", Type.MATERIAL),
new Ingredient("STRAIGHT", "straight", Type.HOLD),
new Ingredient("BEND", "bend", Type.HOLD),
);
Type[] types = Ingredient.Type.values();
for (Type type : types) {
model.addAttribute(type.toString().toLowerCase(),
filterByType(ingredients, type));
}
}
@ModelAttribute(name = "swordOrder")
public SwordOrder order() {
return new SwordOrder();
}
@ModelAttribute(name = "sword")
public Sword sword() {
return new Sword();
}
@GetMapping
public String showDesignForm() {
return "design";
}
private Iterable<Ingredient> filterByType(List<Ingredient> ingredients, Type type) {
return ingredients.stream()
.filter(x -> x.getType().equals(type))
.collect(Collectors.toList());
}
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>design.html</title>
<link rel="stylesheet" th:href="@{/styles.css}" />
</head>
<body>
<h1>Design your sword!</h1>
<img th:src="@{/images/SwordShop.png}"/>
<form method="POST" th:object="${sword}">
<div class="grid">
<div class="ingredient-group" id="blade">
<h3>Designate your blade:</h3>
<div th:each="ingredient : ${blade}">
<input th:field="*{ingredients}" type="checkbox"
th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="material">
<h3>Pick your material:</h3>
<div th:each="ingredient : ${material}">
<input th:field="*{ingredients}" type="checkbox"
th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="hold">
<h3>Choose your hold:</h3>
<div th:each="ingredient : ${hold}">
<input th:field="*{ingredients}" type="checkbox"
th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<h3>Name your sword creation:</h3>
<input type="text" th:field="*{name}"/>
<br/>
<button>Submit Your Sword</button>
</div>
</form>
</body>
</html>
@PostMapping
public String processSword(Sword sword, @ModelAttribute SwordOrder swordOrder) {
swordOrder.addSword(sword);
log.info("Processing sword: {}", sword);
return "redirect:/orders/current";
}
透過controller的@ModelAttribute會預設打進來的request開始幫等等要傳出去的model加上attribute。
除了@ModelAttribute,也加上了一個@SessionAttributes(”swordOrder”),代表要將model中的swordOrder存在session。