Thymeleaf 的形式不是 return 控制器 class 方法的对象
Thymeleaf's form dont return the object to controller class's method
我有一个带有 JPA/Hibernate 的 SpringBoot-MVC Java 应用程序,使用 H2 数据库存储数据,我正尝试通过 Web 浏览器读取和更改该数据库的行。我阅读成功了,但是带有 thymeleaf 的编辑页面表单没有将我更改的对象发送到控制器 class。
公式:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Cadastro de Clientes</title>
<link href="/webjars/bootstrap/4.5.0/css/bootstrap.min.css"
rel="stylesheet"></link>
<script src="/webjars/jquery/3.5.1/jquery.min.js"></script>
<script src="/webjars/bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="panel panel-default">
<div class="panel-heading">
<strong>Edicao de Clientes</strong>
</div>
<div class="panel-body">
<form class="form-horizontal" th:object="${customer}"
th:action="@{/save}" method="post" style="margin: 10px">
<div class="form-group">
<fieldset>
<div class="form-group row">
<div class="alert alert-danger" th:if="${#fields.hasAnyErrors()}">
<div th:each="detailedError : ${#fields.detailedErrors()}">
<span th:text="${detailedError.message}"></span>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-1">
<input type="hidden" class="form-control input-sm"
th:field="*{id}" readonly="readonly" style="display: none;" />
</div>
<div class="col-md-1">
<label>CÓD. DO CLIENTE</label> <input type="text"
class="form-control input-sm" th:field="*{customerId}"
readonly="readonly" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('companyName')}? 'has-error'">
<label>RAZAO SOCIAL</label> <input type="text"
class="form-control input-sm" th:field="*{companyName}"
autofocus="autofocus" placeholder="Informe o texto"
maxlength="50" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('tradeName')}? 'has-error'">
<label>NOME FANTASIA</label> <input type="text"
class="form-control input-sm" th:field="*{tradeName}"
maxlength="150" placeholder="Informe o texto" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('sectorId')}? 'has-error'">
<label>SETOR</label> <input type="text"
class="form-control input-sm" th:field="*{sectorId}" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('neighborhood')}? 'has-error'">
<label>BAIRRO</label>
<textarea class="form-control input-sm"
th:field="*{neighborhood}" placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('place')}? 'has-error'">
<label>LOGRADOURO</label>
<textarea class="form-control input-sm" th:field="*{place}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('neighborhood')}? 'has-error'">
<label>NUMERO</label>
<textarea class="form-control input-sm" th:field="*{placeId}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('city')}? 'has-error'">
<label>CIDADE</label>
<textarea class="form-control input-sm" th:field="*{city}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('visitDay')}? 'has-error'">
<label>DIA DE VISITA</label>
<textarea class="form-control input-sm" th:field="*{visitDay}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('region')}? 'has-error'">
<label>REGIAO</label>
<textarea class="form-control input-sm" th:field="*{region}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('latitude')}? 'has-error'">
<label>LATITUDE</label>
<textarea class="form-control input-sm" th:field="*{latitude}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('longitude')}? 'has-error'">
<label>LONGITUDE</label>
<textarea class="form-control input-sm" th:field="*{longitude}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<button type="submit" class="btn btn-sm btn-primary">Salvar</button>
<a th:href="@{/}" class="btn btn-sm btn-default">Cancelar</a>
</div>
</fieldset>
</div>
</form>
</div>
</div>
</body>
</html>
要接收公式的对象的方法:
package com.br.aloi.planner.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
import com.br.aloi.planner.model.Customer;
import com.br.aloi.planner.service.CustomerService;
@Controller
public class CustomerController {
@Autowired
private CustomerService service;
(...)
@PostMapping("/save")
public ModelAndView save(@Valid Customer customer, BindingResult result) {
if (result.hasErrors()) {
return edit(customer.getId());
}
service.save(customer);
return findAll();
}
}
对象正在向控制器 class 上的 save
方法返回 null。否则,当我在浏览器中 select 一行数据库并单击 'edit' 时,打开的编辑页面将完美地创建对象的属性。
在从 Thymeleaf 请求对象之前,您必须通过您的模型传递对象,以便 Thymeleaf 拥有它。
将以下内容添加到您的控制器方法中:
@ModelAttribute("customer")
public Customer thisPartCanBeCalledWhatever() {
return new Customer();
}
确保客户 class 具有 getter、setter 和默认构造函数。
按照 J Asgarov 的建议,我重新检查了我的模型并重新创建了所有属性的 getter 和 setter。重建项目后,post 立即返回对象。毕竟代码是正确的,我的新手很不安
毕竟。谢谢!!
我有一个带有 JPA/Hibernate 的 SpringBoot-MVC Java 应用程序,使用 H2 数据库存储数据,我正尝试通过 Web 浏览器读取和更改该数据库的行。我阅读成功了,但是带有 thymeleaf 的编辑页面表单没有将我更改的对象发送到控制器 class。
公式:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Cadastro de Clientes</title>
<link href="/webjars/bootstrap/4.5.0/css/bootstrap.min.css"
rel="stylesheet"></link>
<script src="/webjars/jquery/3.5.1/jquery.min.js"></script>
<script src="/webjars/bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="panel panel-default">
<div class="panel-heading">
<strong>Edicao de Clientes</strong>
</div>
<div class="panel-body">
<form class="form-horizontal" th:object="${customer}"
th:action="@{/save}" method="post" style="margin: 10px">
<div class="form-group">
<fieldset>
<div class="form-group row">
<div class="alert alert-danger" th:if="${#fields.hasAnyErrors()}">
<div th:each="detailedError : ${#fields.detailedErrors()}">
<span th:text="${detailedError.message}"></span>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-1">
<input type="hidden" class="form-control input-sm"
th:field="*{id}" readonly="readonly" style="display: none;" />
</div>
<div class="col-md-1">
<label>CÓD. DO CLIENTE</label> <input type="text"
class="form-control input-sm" th:field="*{customerId}"
readonly="readonly" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('companyName')}? 'has-error'">
<label>RAZAO SOCIAL</label> <input type="text"
class="form-control input-sm" th:field="*{companyName}"
autofocus="autofocus" placeholder="Informe o texto"
maxlength="50" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('tradeName')}? 'has-error'">
<label>NOME FANTASIA</label> <input type="text"
class="form-control input-sm" th:field="*{tradeName}"
maxlength="150" placeholder="Informe o texto" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('sectorId')}? 'has-error'">
<label>SETOR</label> <input type="text"
class="form-control input-sm" th:field="*{sectorId}" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('neighborhood')}? 'has-error'">
<label>BAIRRO</label>
<textarea class="form-control input-sm"
th:field="*{neighborhood}" placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('place')}? 'has-error'">
<label>LOGRADOURO</label>
<textarea class="form-control input-sm" th:field="*{place}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('neighborhood')}? 'has-error'">
<label>NUMERO</label>
<textarea class="form-control input-sm" th:field="*{placeId}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('city')}? 'has-error'">
<label>CIDADE</label>
<textarea class="form-control input-sm" th:field="*{city}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('visitDay')}? 'has-error'">
<label>DIA DE VISITA</label>
<textarea class="form-control input-sm" th:field="*{visitDay}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('region')}? 'has-error'">
<label>REGIAO</label>
<textarea class="form-control input-sm" th:field="*{region}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('latitude')}? 'has-error'">
<label>LATITUDE</label>
<textarea class="form-control input-sm" th:field="*{latitude}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"
th:classappend="${#fields.hasErrors('longitude')}? 'has-error'">
<label>LONGITUDE</label>
<textarea class="form-control input-sm" th:field="*{longitude}"
placeholder="Informe o texto"></textarea>
</div>
</div>
<div class="form-group row">
<button type="submit" class="btn btn-sm btn-primary">Salvar</button>
<a th:href="@{/}" class="btn btn-sm btn-default">Cancelar</a>
</div>
</fieldset>
</div>
</form>
</div>
</div>
</body>
</html>
要接收公式的对象的方法:
package com.br.aloi.planner.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
import com.br.aloi.planner.model.Customer;
import com.br.aloi.planner.service.CustomerService;
@Controller
public class CustomerController {
@Autowired
private CustomerService service;
(...)
@PostMapping("/save")
public ModelAndView save(@Valid Customer customer, BindingResult result) {
if (result.hasErrors()) {
return edit(customer.getId());
}
service.save(customer);
return findAll();
}
}
对象正在向控制器 class 上的 save
方法返回 null。否则,当我在浏览器中 select 一行数据库并单击 'edit' 时,打开的编辑页面将完美地创建对象的属性。
在从 Thymeleaf 请求对象之前,您必须通过您的模型传递对象,以便 Thymeleaf 拥有它。
将以下内容添加到您的控制器方法中:
@ModelAttribute("customer")
public Customer thisPartCanBeCalledWhatever() {
return new Customer();
}
确保客户 class 具有 getter、setter 和默认构造函数。
按照 J Asgarov 的建议,我重新检查了我的模型并重新创建了所有属性的 getter 和 setter。重建项目后,post 立即返回对象。毕竟代码是正确的,我的新手很不安 毕竟。谢谢!!