美文网首页
Spring实战(第5版)第三章代码问题

Spring实战(第5版)第三章代码问题

作者: yuq329 | 来源:发表于2020-06-06 22:08 被阅读0次

    Spring实战(第5版)第三章代码问题

    先吐槽。。。这本书代码问题是真的多!

    • application.properties

      spring.thymeleaf.cache=false
      spring.datasource.url=jdbc:h2:mem:db;database_to_upper=false
      spring.datasource.driverClassName=org.h2.Driver
      spring.datasource.username=root
      spring.datasource.password=123456
      spring.datasource.schema=classpath:db/schema.sql
      spring.datasource.data=classpath:db/data.sql
      spring.h2.console.enabled=true
      
      • 数据库初始化文件放在resources/db/文件夹下
    • DesignTacoController问题

      • 主要问题出在表单中的字符串如何转Ingredient
      • design.html
      <!DOCTYPE html>
      <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:th="http://www.thymeleaf.org">
      <head>
          <meta charset="UTF-8">
          <title>Taco Cloud</title>
          <link rel="stylesheet" th:href="@{./styles.css}">
      </head>
      
      <body>
      <h1>Design your taco!</h1>
      <img th:src="@{/images/TacoCloud.png}"/>
      
      <form method="POST" th:object="${taco}">
      
          <span class="validationError"
                th:if="${#fields.hasErrors('ingredients')}"
                th:errors="*{ingredients}">Ingredient Error</span>
      
          <div class="grid">
              <div class="ingredient-group" id="wraps">
                  <h3>Designate your wrap:</h3>
                  <div th:each="ingredient : ${wrap}">
                      <input name="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                      <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="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                      <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="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                      <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="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                      <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="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                      <span th:text="${ingredient.name}">INGREDIENT</span>
                  </div>
              </div>
      
              <h3>Name your taco creation:</h3>
              <input type="text" th:field="*{name}"/>
              <br/>
              <button>Submit your taco</button>
          </div>
      </form>
      </body>
      </html>
      
      • DesignController.java
      package com.yuq.taco;
      
      import com.google.gson.Gson;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Controller;
      import org.springframework.ui.Model;
      import org.springframework.validation.Errors;
      import org.springframework.web.bind.annotation.*;
      
      import javax.validation.Valid;
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.Date;
      import java.util.List;
      import java.util.stream.Collectors;
      
      @Controller
      @RequestMapping("/design")
      @SessionAttributes("order")
      public class DesignTacoController {
      
          private final IngredientRepository ingredientRepo;
          private TacoRepository designRepo;
      
          @Autowired
          public DesignTacoController(IngredientRepository ingredientRepo, TacoRepository designRepo) {
              this.ingredientRepo = ingredientRepo;
              this.designRepo = designRepo;
          }
      
          @ModelAttribute
          public void addIngredientsToModel(Model model) {
              List<Ingredient> ingredients = new ArrayList<>();
              ingredientRepo.findAll().forEach(i -> ingredients.add(i));
              Ingredient.Type[] types = Ingredient.Type.values();
              for (Ingredient.Type type : types) {
                  model.addAttribute(type.toString().toLowerCase(), filterByType(ingredients, type));
              }
          }
      
      
          @ModelAttribute(name = "order")
          public Order order() {
              return new Order();
          }
      
          @ModelAttribute(name = "taco")
          public Taco taco() {
              return new Taco();
          }
      
          @GetMapping
          public String showDesignForm(Model model) {
              return "design";
          }
      
      
          @PostMapping
          public String processDesign(@Valid Taco design, Errors errors, @ModelAttribute Order order) {
              if (errors.hasErrors())
                  return "design";
              Gson gson = new Gson();
              for (String info : design.getIngredientsString()) {
                  Ingredient x=gson.fromJson(info, Ingredient.class);
                  design.addIngredients(x);
              }
              design.setCreatedAt(new Date());
              Taco saved = designRepo.save(design);
              order.addDesign(saved);
              return "redirect:/orders/current";
          }
      
          private List<Ingredient> filterByType(List<Ingredient> ingredients, Ingredient.Type type) {
              return ingredients.stream().filter(x -> x.getType().equals(type)).collect(Collectors.toList());
          }
      }
      
      
      • Ingredient.java
      package com.yuq.taco;
      
      import lombok.Data;
      import lombok.RequiredArgsConstructor;
      
      @Data
      @RequiredArgsConstructor
      public class Ingredient {
          private final String id;
          private final String name;
          private final Type type;
      
          public static enum Type {
              WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
          }
      
          @Override
          public String toString() {
              return "{'id':'" + id + "\'" + ", 'name':'" + name + "\'" + ", 'type':'" + type + "\'}";
          }
      }
      
      
      • 添加Gson依赖
          <dependency>
              <groupId>com.google.code.gson</groupId>
              <artifactId>gson</artifactId>
              <version>2.8.1</version>
          </dependency>
      
      
      package com.yuq.taco;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.jdbc.core.JdbcTemplate;
      import org.springframework.jdbc.core.PreparedStatementCreator;
      import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
      import org.springframework.jdbc.support.GeneratedKeyHolder;
      import org.springframework.jdbc.support.KeyHolder;
      import org.springframework.stereotype.Repository;
      
      import java.sql.*;
      import java.util.Arrays;
      import java.util.Date;
      
      @Repository
      public class JdbcTacoRepository implements TacoRepository{
      
          private JdbcTemplate jdbc;
      
          @Autowired
          public JdbcTacoRepository(JdbcTemplate jdbc){
              this.jdbc=jdbc;
          }
      
          @Override
          public Taco save(Taco design) {
              long tacoId=saveTacoInfo(design);
              design.setId(tacoId);
              for(Ingredient ingredient:design.getIngredients()){
                  saveIngredientToTaco(ingredient,tacoId);
              }
              return design;
          }
      
          private long saveTacoInfo(Taco taco){
      //        PreparedStatementCreator psc = new PreparedStatementCreatorFactory(
      //                "insert into Taco (name,createdAt) values (?,?);",
      //                Types.VARCHAR,Types.TIMESTAMP
      //        ).newPreparedStatementCreator(Arrays.asList(taco.getName(),new Timestamp(taco.getCreatedAt().getTime())));
      //
      //        KeyHolder keyHolder=new GeneratedKeyHolder();
      //        jdbc.update(psc,keyHolder);
      
              String sql = "insert into Taco (name,createdAt) values (?,?);";
              KeyHolder keyHolder = new GeneratedKeyHolder();
              jdbc.update(new PreparedStatementCreator() {
                  @Override
                  public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                      // 指定主键
                      PreparedStatement preparedStatement = connection.prepareStatement(sql, new String[]{"id"});
                      preparedStatement.setString(1, taco.getName());
                      preparedStatement.setTimestamp(2, new Timestamp(taco.getCreatedAt().getTime()));
                      return preparedStatement;
                  }
              }, keyHolder);
              return keyHolder.getKey().longValue();
          }
      
          private void saveIngredientToTaco(Ingredient ingredient,long tacoId){
              jdbc.update("insert into Taco_Ingredients (taco,ingredient) values(?,?)",tacoId,ingredient.getId());
          }
      
      
      }
      
    • OrderController

      • 没什么问题,主要是表单中的数据名字与数据库中的不一致,改下数据库就可以
      create table if not exists Taco_Order(
          id identity,
          name varchar(50) not null,
          street varchar(50) not null,
          city varchar(50) not null,
          state varchar(2) not null,
          zip varchar(10) not null,
          ccNumber varchar(16) not null,
          ccExpiration varchar(5) not null,
          ccCVV varchar(3) not null,
          placedAt timestamp not null
      );
      

    代码链接

    百度云链接:https://pan.baidu.com/s/1GPXLeZ1SfJ1qyfQuNlaA_Q 密码:7up3

    相关文章

      网友评论

          本文标题:Spring实战(第5版)第三章代码问题

          本文链接:https://www.haomeiwen.com/subject/tgyozhtx.html