引言
最近開始學習Spring,瞭解到《Spring實戰》已經出到第五版了,遂打算跟著《Spring實戰(第五版)》來入門Spring,沒想到這書一點也不嚴謹,才看到第三章就發現了多處程式碼問題。
此外,有很多地方都是含糊其辭沒有說清楚,如果說此書面向小白卻又不注重細節,如果說此書面向有spring基礎的人卻又過於淺顯,吐槽到此結束。
本文記錄《Spring In Action 5th》中遇到的錯誤,長期更新。
第二章
如果你也是一步步跟著《Spring In Action 5th》一步步下來,你會在2.1節遇到一段跑不通的程式碼,在程式清單2.2中使用了下一節才提到的類Taco,這不是什麼大問題,翻到2.2節把Taco類定義好就可以了。同理還有Order類。
第三章
3.1使用JDBC讀寫資料
訪問H2 Console
首先應該注意h2資料庫,根據書中所說,H2資料庫不需要額外的配置,即你不需要按照其他博主所說去application.properties(或.yml)中去配置h2資料庫,只需按書中的步驟做就可以了。
按照書中的配置方法,預設的H2 console訪問連結是:localhost:8080/h2-console。訪問h2-console並不是必須的,但如果你想看的話,把程式跑起來,訪問此連結,並在程式的控制檯日誌中找到類似
H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:0409e967-692c-4378-868e-d9790aeff5ca'
at後面引號中的名稱即你此次執行建立的記憶體資料庫,在h2-console中JDBC URL中填入此字串並連線,即可訪問資料庫。【注意】這種方式下,資料庫名(JDBC URL)每次執行都會變動。
常見錯誤
schema.sql和data.sql中很容易出現拼寫錯誤,並且報錯非常鬼畜,至少我debug了半天才找到錯誤。
缺少addDesign方法
在DesignTacosController.processDesign中呼叫了order.addDesign方法,而此時addDesign還未定義,將Order類的定義補充如下:
import ... @Data public class Order { private Long id; private Date placeAt; private ArrayList<Taco> tacos = new ArrayList<>(); public void addDesign(Taco design) { this.tacos.add(design); } @NotBlank(message="Delivery name is required") private String deliveryName; @NotBlank(message="Street is required") private String deliveryStreet; @NotBlank(message="City is required") private String deliveryCity; @NotBlank(message="State is required") private String deliveryState; @NotBlank(message="Zip code is required") private String deliveryZip; @CreditCardNumber(message="Not a valid credit card number") private String ccNumber; @Pattern(regexp="^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$", message="Must be formatted MM/YY") private String ccExpiration; @Digits(integer=3, fraction=0, message="Invalid CVV") private String ccCVV; }
儲存Ingredient錯誤
如果你在desin頁面提交表單後遇到如下報錯:
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.xiepingfu.tacocloud.Ingredient for property ingredients[0]: no matching editors or conversion strategy found
是因為表單中的Ingredient都是String型別,而此時沒有辦法將String型別轉化為Ingredient,需要配置Converter類將Sring轉化為Ingredient類,新增IngredientByIdConverter類可解決此問題。
import ...import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; @Component public class IngredientByIdConverter implements Converter<String, Ingredient> { private IngredientRepository ingredientRepo; @Autowired public IngredientByIdConverter(IngredientRepository ingredientRepo) { this.ingredientRepo = ingredientRepo; } @Override public Ingredient convert(String id) { return ingredientRepo.findOne(id); } }
注意import的Converter介面必須為Spring框架提供的,即:org.springframework.core.convert.converter.Converter。
解析thymeleaf tmeplate錯誤
到此時,書中程式碼在design頁面提交後會出現如下錯誤:
An error happened during template parsing (template: "class path resource [templates/orderForm.html]") org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/orderForm.html]")
書中出現這樣的錯誤對不熟悉thymeleaf的人非常不友好,提交表單後連結被重定向至'/orders/current',問題就出在OrderController類中,orderForm方法沒有傳入order物件,將orderForm方法暫時修改為
@GetMapping("/current") public String orderForm(Model model) { model.addAttribute("order", new Order()); return "orderForm"; }
可解決此問題。