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"; }
可解决此问题。