当前位置: 首页 > 知识库问答 >
问题:

Spring Boot Thymeleaf: th无法解析Spring EL表达式

王念
2023-03-14

我使用的是spring boot thymeleaf neo4j。除了thymeleaf无法解析模板product_网格中th:each块中使用的'product'变量的一些属性外,其他一切都正常工作。html,其中包括表单标记中的th:src=“${product.URL}”、th:text=“${product.title}”和th:action=“@{/product/(${product.getId()})”表达式。th:text=“${Product.Price}”正在运行。当我检查浏览器中生成的代码时,src标记为空(src:),包含title标记的text属性不会显示在浏览器中。th:action可以正常工作,但是当我单击表单中定义的按钮时,url会变为http://localhost:8080/product/?btn=View产品,而不是浏览器控制台中显示的以下代码http://localhost:8080/product/?1

注意:我试图从存储在neo4j数据库中的字段中获取图像网址。项目目录是:项目目录映像

模板:product_grid.html

<html xmlns:th="http://www.thymeleaf.org" >
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Products</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js" integrity="sha384-feJI7QwhOS+hwpX2zkaeJQjeiwlhOP+SdQDqhgvvo1DsjtiSQByFdThsxO669S2D"
            crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
          crossorigin="anonymous">
</head>

<body>


<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <a class="navbar-brand" href="#">Grada</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
            aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item ">
                <a class="nav-link" href="#">Home
                    <span class="sr-only">(current)</span>
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link">My Best Products</a>
            </li>

            <li class="nav-item">
                <a class="nav-link" th:href="@{/login}">Login</a>
            </li>
        </ul>
        <form class="form-inline my-2 my-lg-0">
            <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
            <a class="btn btn-outline-success my-2 my-sm-0" href="file:///home/madhav/SPM/Grada/public_html/product.html">Search</a>
        </form>
    </div>
</nav>
<div class="container text-center">
    <div class="row">
        <div th:each="Product:${products}" class="col-lg-3 col-sm-12 col-md-6 my-2 p-auto">
            <div class="card">
                <div class="card-body">
                    <img src="http://via.placeholder.com/150x150/888/111" th:src="${Product.URL}" alt="img" class="card-img-top img-thumbnail img-fluid">
                    <div class="card-title lead" th:text="${Product.title}">Some product name</div>
                    <div class="card-text">Price: &#8377;<span th:text="${Product.Price}">400</span></div>
                </div>
                <form method="GET" action="/" th:action="@{/product/(${Product.getId()})}">
                    <input type="submit" name="btn" class="form-control btn btn-primary" value="View Product">
                    <input type="submit" name="btn" class="form-control btn btn-primary" value="Add to Cart">
                </form>
            </div>
        </div>
    </div>
</div>

</body>
</html>`

产品型号:Product.html

package com.grada.ecommerce.Models;


import com.grada.ecommerce.Models.Seller;
import org.neo4j.ogm.annotation.*;


import java.util.HashSet;
import java.util.Set;


@NodeEntity(label = "Product")
public class Product
{
    public  Product()
    {
    }

    public Product(String title, Double price, int quantity, float rating, String description, String url, String company)
    {
        this.title  = title;
        this.Rating = rating;
        this.Description = description;
        this.Price = price;
        this.Quantity = quantity;
        this.URL = url;
        this.Company = company;
    }

    @Id
    @GeneratedValue
    private Long id;

    @Property(name = "title")
    public String title;
    
    @Property(name = "Rating")
    public float Rating;
    @Property(name = "Description")
    public String Description;
    @Property(name = "Price")
    public Double Price;
    @Property(name = "Quantity")
    public int Quantity;
    @Property(name = "Company")
    public String Company;
    @Property(name = "URL")
    public String URL;


    @Override
    public String toString()
    {
        return this.title;
    }

    public Long getId() {
        return id;
    }

    public String getTitle()
    {
        return title;
    }

   @Relationship(type = "Sells", direction = Relationship.INCOMING)
   public Seller Seller;

}
package com.grada.ecommerce.Controllers;

import com.grada.ecommerce.Models.Product;
import com.grada.ecommerce.Models.Seller;
import com.grada.ecommerce.Services.ProductService;
import com.grada.ecommerce.Services.SellerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class ProductController
{

    final ProductService productService;
    final SellerService sellerService;

    @Autowired
    public ProductController(ProductService productService, SellerService sellerService)
    {
        this.productService = productService;
        this.sellerService = sellerService;
    }

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String Index(Model model)
    {
        Iterable<Product> products  = productService.products();
        model.addAttribute("products", products);
        return "product_grid";
    }

    @RequestMapping(value = "/product", method = RequestMethod.GET)
    public String ShowProduct(@RequestParam(value = "id") Long id, Model model)
    {
        Product product = productService.findProductByID(id);
        if(product == null)
            return "redirect:/";
        model.addAttribute("product", product);
        return "productid";
    }

    @RequestMapping(value = "/add")
    public String AddProduct(Model model)
    {
        model.addAttribute("product", new Product());
        return "add";
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String AddProduct(@ModelAttribute Product product)
    {
        productService.addProduct(product);
        return "redirect:/";
    }

    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    public String DeleteProduct(Model model)
    {
        model.addAttribute("product", new Product());
        return "delete";
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public String DeleteProduct(@ModelAttribute Product product)
    {
        productService.deleteProduct(product);
        return "redirect:/";
    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String LoginPage(Model model)
    {
        return "login";
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String Authenticate(Model model, String username, String password)
    {
        if (username.equalsIgnoreCase("seller@fake.com") && password.equals("fakeseller"))
        {
            Iterable<Product> products  = productService.products();
            model.addAttribute("products", products);
            return "loggedin";
        }

        else
            return "redirect:/login";
    }

    @RequestMapping(value = "/policy", method = RequestMethod.GET)
    public String PolicyPage()
    {
        return "policies";
    }
}

共有1个答案

益麻雀
2023-03-14

欢迎来到SO

在产品类中为变量包含setX方法。胸花需要这些来捆绑。

IMO,一个很好的方法是使用Project Lombok,简单地用@Data注释你的类。然后您甚至不需要指定getters或setters(或您的toString())。

变量使用小写,因为按惯例,大写首字母的变量指的是类,而不是实例变量。

如上所述,在表单中使用POST而不是GET,因为您正在提交数据。

使用速记@GetMapping@PostMapping使其更易于阅读。

 类似资料:
  • 问题内容: 尝试在模板中合并多个值时遇到问题。根据Thymeleaf的说法,我应该可以将它们+一起组合在一起… 4.6合并文本 文本,无论它们是文字还是评估变量或消息表达式的结果,都可以使用+运算符轻松连接: 这是我发现有效的示例: 但是,这不是: 从逻辑上讲,这应该可以,但是不能,我在做什么错? Maven: 这是我设置TemplateEngine和TemplateResolver的方法: Th

  • 我对thymeleaf是新手,不明白这个错误。

  • 我正在寻找一个JAVA库来解析 我的要求: 支持所有的值类型(例如int,双,布尔,String等) 支持所有已知的数学 有什么建议吗?

  • 错误4904---[nio-8080-exec-1]org.THYMELEAF.templateEngine :[THYMELEAF][http-nio-8080-exec-1]异常处理模板“index”:模板分析期间出错(模板:“class path resource[templates/index.html]”) org.thymeleaf.exceptions.templateInputEx

  • 有人能帮我理解为什么我对elasticsearch分析器的理解是错误的吗? 我有一个包含各种字段的索引,特别是: 如下所示: 并且 的理解是,它将标记一个句子,以便在出现任意数量的或或时拆分它们。例如,给定模式,以下句子: 我希望看到: 我可以从https://regex101.com/ 然而,当我对上面的句子运行words\u only\u分析器时: 我得到, 这告诉我句子被标记为: 在我看来,

  • 由来 很多JavaBean嵌套有很多层对象,这其中还夹杂着Map、Collection等对象,因此获取太深的嵌套对象会让代码变得冗长不堪。因此我们可以考虑使用一种表达式还获取指定深度的对象,于是BeanResolver应运而生。 原理 通过传入一个表达式,按照表达式的规则获取bean下指定的对象。 表达式分为两种: .表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值 []表