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";
}

可解决此问题。

 

Tags: