《spring实战》第五版第二章org.thymeleaf.exceptions.TemplateInputException

org.thymeleaf.exceptions.TemplateInputException

《Spring实战》这本书买了一段时间了,一直没时间看,正好最近空了,打算照着书里练练手,书还是比较细的,各种讲解都比较具体。

但是跟着书走,在第二章倒数第三小节的时候,就遇到了问题。

总的来说,就是书上地址重定向处的代码写漏了,导致我改到裂开,可能是作者当时SpringBoot版本支持那种写法,但我使用的这个版本不支持吧。

问题描述:
第二章的后半部分是要实现一个逻辑,如下图所示:
在这里插入图片描述
其实就一个简单的重定向,但是当我测试输入错误,重定向返回design页面时,页面直接报错
改了老半天,各种方法都试了,甚至下载了书本配套的源码,进行了细致的比对,发现几乎一模一样,完全没有理由报错,头都改秃了。。。。
真的人傻掉!

具体报错如下:

This application has no explicit mapping for /error, so you are seeing this as a fallback.
There was an unexpected error (type=Internal Server Error, status=500).An error happened during template parsing (template: "class path resource [templates/design.html]")org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/design.html]")
	at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
	at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
	at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
	......
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "#fields.hasErrors('ingredients')" (template: "design" - line 17, col 11)
	at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
	at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
	at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
	... 48 more
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#fields.hasErrors('ingredients')" (template: "design" - line 17, col 11)
	at org.thymeleaf.spring5.expression.SPELVariableExpressionEvaluator.evaluate(SPELVariableExpressionEvaluator.java:290)
	at org.thymeleaf.standard.expression.VariableExpression.executeVariableExpression(VariableExpression.java:166)

以上只是报错的一部分

后面试了各种方法,我终于可以确定是它代码的锅,和配置、操作都没有瓜葛。
书上DesignTacoController.java原码如下所示:

package tacos.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import tacos.Ingredient;

import tacos.Taco;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: 淡
 * @createDate: 2020-11-28 21:01
 * @version: 1.0
 */
@Slf4j
@Controller
@RequestMapping("/design")
public class DesignTacoController {

    @GetMapping
    public String showDesignForm(Model model){
        //获取可用的taco配料,并将其放入到列表中
        //此处的内容会传递到design.html页面,放于复选框
        List<Ingredient> ingredients = Arrays.asList(
                new Ingredient("FLTO","Flour Tortilla", Ingredient.Type.WRAP),
                new Ingredient("COTO","Corn Tortilla", Ingredient.Type.WRAP),
                new Ingredient("奶子","奶子是必要的", Ingredient.Type.WRAP),
                new Ingredient("GRBF","Ground Beef", Ingredient.Type.PROTEIN),
                new Ingredient("CARN","Carnitas", Ingredient.Type.PROTEIN),
                new Ingredient("TMTO","Diced Tomatoes", Ingredient.Type.VEGGIES),

                new Ingredient("LETC","Lettuce", Ingredient.Type.VEGGIES),
                new Ingredient("CHED","Cheddar", Ingredient.Type.CHEESE),
                new Ingredient("JACK","Monterrey Jack", Ingredient.Type.CHEESE),
                new Ingredient("SLSA","Salsa", Ingredient.Type.SAUCE),
                new Ingredient("SRCR","Sour Cream", Ingredient.Type.SAUCE)
        );
        Ingredient.Type[]  types = Ingredient.Type.values();
        // 配料类型的列表,会作为属性添加到Model对象上
        // 这个对象以参数的形式传递到本方法中
        for (Ingredient.Type type :
                types) {
            //.toLowerCase的意思是将所有的英文字符转换为小写字母
            model.addAttribute(type.toString().toLowerCase(),
                    filterByType(ingredients, type));
        }

        model.addAttribute("design", new Taco());

        return "design";
    }



    private List<Ingredient> filterByType(List<Ingredient> ingredients, Ingredient.Type type){
        return ingredients
                .stream()
                .filter(x-> x.getType().equals(type))
                .collect(Collectors.toList());
    }

    /**
     * 完成processDesign()后,
     * <br/>
     * 用户的浏览器会重定向到相对路径“/orders/current”
     * <br/>
     * @param design
     * @return java.lang.String
     * @author 淡
     * @date 2020/11/29 15:46
     */
    @PostMapping
    public String processDesign(@Valid Taco design, Errors errors){
        if (errors.hasErrors()){
            return "design";
        }
        // save the taco design...
        // we'll do this in chapter 3
        log.info("Processing design: "+ design);
        // 返回的值代表了一个要展现给用户的视图,带有“redirect”前缀,表明这是一个重定向视图
        // 完成processDesign()后,用户的浏览器会重定向到相对路径“/orders/current”
        return "redirect:/orders/current";
    }


}

出错的是这个方法:

/**
 * 完成processDesign()后,如果成功:
 * <br/>
 * 用户的浏览器会重定向到相对路径“/orders/current”
 * <br/>
 * 如果失败:返回/design
 * <br/>
 * @param design
 * @return java.lang.String
 * @author 淡
 * @date 2020/11/29 15:46
 */
@PostMapping
public String processDesign(@Valid Taco design, Errors errors){
    if (errors.hasErrors()){
        return "design";
    }
    // save the taco design...
    // we'll do this in chapter 3
    log.info("Processing design: "+ design);
    // 返回的值代表了一个要展现给用户的视图,带有“redirect”前缀,表明这是一个重定向视图
    // 完成processDesign()后,用户的浏览器会重定向到相对路径“/orders/current”
    return "redirect:/orders/current";
}

把这句:

if (errors.hasErrors()){
        return "design";
    }

修改成:

if (errors.hasErrors()){
       return "redirect:/design";
   }

问题顺利解决!!!

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值