iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0
自我挑戰組

Spring In Action系列 第 4

Controller

  • 分享至 

  • xImage
  •  

這段在實作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。


上一篇
Model
下一篇
Between Front & Back
系列文
Spring In Action30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言