使用Thymeleaf在Spring Boot App中提交表单的问题

时间:2018-06-15 08:28:06

标签: spring-boot thymeleaf

我有这个用Spring Boot编写的基本应用程序,带有一个Web控制器。我添加了一个HTML表单来添加一些输入,这些输入将使用JpaRepository save方法保存输入。

我使用Thymeleaf作为我的模板引擎,MySql作为DB。当我运行应用程序时,它运行得很好。但是,当我点击localhost:8080 / addExpense页面时,它会出现一个白标错误页面,其中包含以下错误:

  

出现意外错误(type = Internal Server Error,   状态= 500)。       执行处理器期间出错&org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor'   (模板:" addExpense" - 第19行,第49栏)

我认为问题在于此代码

  

个:字段=" * {费用}"

我的IDE控制台会输出以下错误:

  

org.thymeleaf.exceptions.TemplateProcessingException:期间出错   执行处理器   ' org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor'   (模板:" addExpense" - 第19行,第49栏)at   org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117)   〜[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)   〜[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.util.ProcessorConfigurationUtils $ ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)   〜[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918)   〜[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.engine.StandaloneElementTag.beHandled(StandaloneElementTag.java:228)   〜[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136)   〜[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:661)   〜[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)   [thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)   [thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:354)   [thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:187)   [thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)   [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)   [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)   [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)   [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)   [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)   [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   javax.servlet.http.HttpServlet.service(HttpServlet.java:635)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)   [spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   javax.servlet.http.HttpServlet.service(HttpServlet.java:742)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)   [tomcat-embed-websocket-8.5.31.jar:8.5.31] at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)   [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)   [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)   [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)   [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)   [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)   [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)   [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)   [spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.coyote.AbstractProtocol $ ConnectionHandler.process(AbstractProtocol.java:790)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1468)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)   [na:1.8.0_161] at   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:624)   [na:1.8.0_161] at   org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)   [tomcat-embed-core-8.5.31.jar:8.5.31] at   java.lang.Thread.run(Thread.java:748)[na:1.8.0_161]引起:   java.lang.IllegalStateException:既不是BindingResult也不是普通的   bean名称的目标对象'费用'可用作请求属性     在   org.springframework.web.servlet.support.BindStatus。(BindStatus.java:153)   〜[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903)   〜[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE] at   org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227)   〜[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:305)   〜[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:252)   〜[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:226)   〜[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174)   〜[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE] at   org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)   〜[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] ... 56个常见框架   省略

Here's my codes:

Model File: Expense.java

package com.ksk.expenseapp.model;


import javax.persistence.*;
import java.time.LocalDate;

@Entity
public class Expense {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "date")
    private String date;

    @Column(name = "expense")
    private String expense;

    @Column(name = "amount")
    private int amount;

    //No Arg Construction required by JPA
    public Expense() {
    }

    public Expense(String expense, int amount) {
        this.date = LocalDate.now().toString();
        this.expense = expense;
        this.amount = amount;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getExpense() {
        return expense;
    }

    public void setExpense(String expense) {
        this.expense = expense;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }
}

网络控制器文件

package com.ksk.expenseapp.controller;

import com.ksk.expenseapp.model.Expense;
import com.ksk.expenseapp.repo.ExpenseRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class WebController {

    ExpenseRepo expenseRepo;

    @Autowired
    public WebController(ExpenseRepo expenseRepo) {
        this.expenseRepo = expenseRepo;
    }

    @RequestMapping("/addExpense")
    public String addExpense(){
        return "addExpense";
    }

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String addNewExpense(@ModelAttribute Expense expense){
        expenseRepo.save(expense);
        return "addExpense";
    }
}

AddExpense html file

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"/>

    <title>Hello, world!</title>
</head>
<body>
<h1>Add Expense</h1>

<form th:action="@{/save}" th:object="${expense}" method="post">
    <div class="form-group">
        <label>Expense</label>
        <input type="text" class="form-control" th:field="*{expense}"/>

        <label>Amount</label>
        <input type="text" class="form-control"  th:field="*{amount}"/>
        <button class="btn btn-success" type="submit">Submit</button>
    </div>

</form>


<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" 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>
</body>
</html>

0 个答案:

没有答案