spring引导将onomy realionship请求值Map到控制器模型

fcipmucu  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(498)

好的,我开始学习springboot了,我正在努力在客户机上进行模型值Map。
使用标准字段似乎可以,但是当我有一个表示两个表之间关系的字段时,系统似乎无法自动识别所选的值,尽管看起来很直观,它应该能够做到这一点。
所以,我有两个反映银行和客户的模型类,每个客户都有一个关联的银行:
这是客户端类

  1. package databaseModel;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.GenerationType;
  5. import javax.persistence.Id;
  6. import javax.persistence.JoinColumn;
  7. import javax.persistence.ManyToOne;
  8. @Entity
  9. public class Clientes {
  10. @Id
  11. @GeneratedValue(strategy=GenerationType.IDENTITY)
  12. private Integer id;
  13. @ManyToOne
  14. @JoinColumn(name = "id_banco")
  15. private Banco banco;
  16. private String nombre;
  17. private String apellidos;
  18. private String direccion;
  19. private String documento;
  20. public Integer getId() {
  21. return id;
  22. }
  23. public void setId(Integer id) {
  24. this.id = id;
  25. }
  26. public Banco getBanco() {
  27. return banco;
  28. }
  29. public void setBanco(Banco banco) {
  30. this.banco = banco;
  31. }
  32. public String getNombre() {
  33. return nombre;
  34. }
  35. public void setNombre(String nombre) {
  36. this.nombre = nombre;
  37. }
  38. public String getApellidos() {
  39. return apellidos;
  40. }
  41. public void setApellidos(String apellidos) {
  42. this.apellidos = apellidos;
  43. }
  44. public String getDireccion() {
  45. return direccion;
  46. }
  47. public void setDireccion(String direccion) {
  48. this.direccion = direccion;
  49. }
  50. public String getDocumento() {
  51. return documento;
  52. }
  53. public void setDocumento(String documento) {
  54. this.documento = documento;
  55. }
  56. }

这是银行舱

  1. package databaseModel;
  2. import java.util.List;
  3. import javax.persistence.Entity;
  4. import javax.persistence.GeneratedValue;
  5. import javax.persistence.GenerationType;
  6. import javax.persistence.Id;
  7. import javax.persistence.OneToMany;
  8. @Entity
  9. public class Banco {
  10. @Id
  11. @GeneratedValue(strategy=GenerationType.IDENTITY)
  12. private Integer id;
  13. private String cif;
  14. private String bic;
  15. private String direccion;
  16. private String nombre;
  17. @OneToMany(mappedBy = "banco")
  18. private List<Clientes> clientes;
  19. public Integer getId() {
  20. return id;
  21. }
  22. public void setId(Integer id) {
  23. this.id = id;
  24. }
  25. public String getCif() {
  26. return cif;
  27. }
  28. public void setCif(String cif) {
  29. this.cif = cif;
  30. }
  31. public String getBic() {
  32. return bic;
  33. }
  34. public void setBic(String bic) {
  35. this.bic = bic;
  36. }
  37. public String getDireccion() {
  38. return direccion;
  39. }
  40. public void setDireccion(String direccion) {
  41. this.direccion = direccion;
  42. }
  43. public String getNombre() {
  44. return nombre;
  45. }
  46. public void setNombre(String nombre) {
  47. this.nombre = nombre;
  48. }
  49. }

现在,我正在尝试创建一个可以添加新客户机的页面。为此,我有两个控制器方法,一个用于管理表单呈现,另一个用于检索转换为客户机模型的表单数据并将其保存到数据库。
以下是我的控制器方法:

  1. @Controller
  2. public class Controladores {
  3. @Autowired
  4. private ClientesRepository clientes;
  5. @Autowired
  6. private BancoRepository bancos;
  7. @GetMapping("/nuevoCliente")
  8. public String nuevoCliente(Model model) {
  9. Clientes nuevoCliente = new Clientes();
  10. model.addAttribute("cliente", nuevoCliente);
  11. model.addAttribute("bancos", bancos.findAll());
  12. return "nuevoCliente";
  13. }
  14. @PostMapping("/nuevoCliente")
  15. public String nuevoCliente(@ModelAttribute Clientes nuevoCliente, Model model) {
  16. clientes.save(nuevoCliente);
  17. model.addAttribute("clientes", clientes.findAll());
  18. return "gestionClientes";
  19. }
  20. }

最后,我还有一个视图,其中呈现了一个窗体,这样用户就可以向服务器发送新的客户端数据:

  1. <!DOCTYPE HTML>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <title>Gestión bancaria</title>
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  6. </head>
  7. <body>
  8. <p>Alta de un nuevo usuario, por favor, introduce los datos del usuario y pulsa el botón guardar</p>
  9. <form method="post" action="#" th:action="@{/nuevoCliente}" th:object="${cliente}">
  10. <input type="text" th:field="*{nombre}" placeholder="Nombre" />
  11. <input type="text" th:field="*{apellidos}" placeholder="Apellidos" />
  12. <input type="text" th:field="*{documento}" placeholder="NIF" />
  13. <input type="text" th:field="*{direccion}" placeholder="Dirección" />
  14. <select th:field="*{banco}">
  15. <option th:each="banco: ${bancos}" th:value="${banco}" th:text=${banco.nombre} />
  16. </select>
  17. <input type="submit" value="Guardar" />
  18. </form>
  19. </body>
  20. </html>

现在,当我尝试发送表单时,出现了一个异常:
出现意外错误(类型=错误请求,状态=400)。对object='clientes'的验证失败。错误计数:1 org.springframework.validation.bindexception:org.springframework.validation.beanpropertybindingresult:1 errors字段“banco”上的对象“clientes”中存在错误:拒绝值[databasemodel]。banco@5adaf23d]; 代码[typemismatch.clientes.banco,typemismatch.banco,typemismatch.databasemodel.banco,typemismatch];参数[org.springframework.context.support.defaultmessagesourceresolvable:代码[clientes.banco,banco];参数[];默认消息[银行]];默认消息[未能将类型为'java.lang.string'的属性值转换为属性'banco'所需的类型'databasemodel.banco';嵌套异常为org.springframework.core.convert.conversionfailedexception:未能将值'databasemodel'的类型[java.lang.string]转换为类型[java.lang.integer]。banco@5adaf23d'; 嵌套异常为java.lang.numberformatexception:对于输入字符串:“databasemodel。banco@5adaf23d"]
据我所知。。。框架无法将存储在bank select上的值转换为bank类类型。我想知道。。。如果一切都正确连接,那么引擎不应该正确猜测哪些数据必须加载到新的客户机对象banco属性中吗?

4sup72z8

4sup72z81#

你说得对:是的 <option ... /> 标记保存 Banco 物体,例如 databaseModel.Banco@212313221 . 它不能绑定到 Banco 对象。
最简单的解决办法是只保留 banco.id ( th:field 以及 th:value 属性):

  1. <select th:field="*{banco.id}">
  2. <option th:each="banco: ${bancos}" th:value="${banco.id}" th:text=${banco.nombre} />
  3. </select>

它会工作,但你会得到一个不完整的 Banco 在控制器中:仅 id 会被设定的。您需要手动执行数据库lookap。
另一种选择是创建自定义类型转换器。这个 <select> tag将发送 banco.id 作为 client.banco ,转换器将执行db查找。

  1. <select th:field="*{banco}">
  2. <option th:each="banco: ${bancos}" th:value="${banco.id}" th:text=${banco.nombre} />
  3. </select>
  1. @Component
  2. public class BancoConverter implements Converter<String, Banco> {
  3. @Autowired
  4. private BancoRepository bancos;
  5. @Override
  6. public Banco convert(String id) {
  7. return bancos.findById(Integer.parseInt(id));
  8. }
  9. }
展开查看全部

相关问题