1. 程式人生 > >Spring In Action 5th中的一些錯誤

Spring In Action 5th中的一些錯誤

引言

最近開始學習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";
}

可解決此問題。