【问题标题】:A spring request give me only null春季请求只给我空
【发布时间】:2020-09-27 18:07:38
【问题描述】:

问题是,我正在做一个基于网络的课堂作业,用 spring 和 Thymeleaf 管理一个仓库。问题是,当使用 Thymeleaf 在页面上放置具有动态选择的表单时,尝试检索信息只会给我一个又一个空值。我想要一些天才来帮助我找出确切的问题是什么,因为我已经在这里待了大约 3 个小时,但我无法解决它。提前致谢。

这将是控制器:

@Controller
public class MiControlador {

    @Autowired
    IProductoSERVICE productoService;
    
    @Autowired
    IAlmacenSERVICE almacenService;
    
    @Autowired
    IVentaSERVICE ventaService;
    
    ...

    @RequestMapping("/productos")
    public String verProductos(Model model) {
        System.out.println(almacenService.findAll());
        model.addAttribute("almacenes", almacenService.findAll());
        return "productos.html";
    }
    @RequestMapping("/productos/selalm")
    public String verProductos(@RequestParam(value = "idAlmacenes", required = false) Integer idAlmacenes, Model model) {
        System.out.println("paso 1");
        System.out.println(idAlmacenes);
        List<Producto> productos = productoService.findByAlm(idAlmacenes);
        System.out.println("Paso 2");
        System.out.println(productos.toString());
        model.addAttribute("productos", productos);
        System.out.println("Paso 3");
        return "productos.html";
    }

在“verProductos”方法中,我想要查看特定仓库的产品。

这将是 Html:

<html xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" 
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" 
crossorigin="anonymous">
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
productos
<form th:action="@{/productos/selalm}" th:field= "*{idAlmacenes}" method="post">
    <select class="form-control" >
      <option th:each= "almacen: ${almacenes}" th:text= "${almacen.nombre}" th:value= "${almacen.idalmacenes}"></option>
    </select>
    <Input type="submit" th:value= "Mostrar">
</form>
<table class="table">
  <thead>
    <tr>
      <th scope="col">Id de producto</th>
      <th scope="col">Nombre</th>
      <th scope="col">Precio</th>
    </tr>
  </thead>
  <tbody>
    <tr th:each="producto: ${productos}">
         <td th:text="${producto.idproductos}">...</td>
         <td th:text="${producto.nombre}">...</td>
         <td th:text="${producto.precioUnitario}">...</td>
      </tr>
  </tbody>
</table>
</body>
</html>

正如您在开始时看到的那样,我放置了一个带有“选择”的表单来选择我要检查的仓库,并将其发送到控制器“/selalm”,目的是从BDD 并将其发送回“products.html”以填写我在下面放置的表格。 问题是,当涉及到打印“Paso 1”甚至“Integer idAlmacenes”时,无论我做什么,后者都会将其打印为 null。

最后,这是我的“Almacen”课程:

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="almacenes")
public class Almacen {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    public int idalmacenes;
    public String nombre;
    public String ubicacion;
    
    public Almacen() {
        super();
    }

    public Almacen(int idalmacenes, String nombre, String ubicacion) {
        super();
        this.idalmacenes = idalmacenes;
        this.nombre = nombre;
        this.ubicacion = ubicacion;
    }

    public int getId() {
        return idalmacenes;
    }

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

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getUbicacion() {
        return ubicacion;
    }

    public void setUbicacion(String ubicacion) {
        this.ubicacion = ubicacion;
    }

    @Override
    public String toString() {
        return "Almacen [idalmacenes=" + idalmacenes + ", nombre=" + nombre + ", ubicacion=" + ubicacion + "]";
    }
        
}

提前感谢大家。

【问题讨论】:

  • 我无法完全理解 null 是什么? idAlmacenes 或 productos 是否为空?如果 idAlmacenes 不为 null 但 productos 为 null,那么您还应该共享 Service 类。
  • 能否提供异常堆栈跟踪?
  • 在" public String verProductos(@RequestParam(value = "idAlmacenes"", idAlmacenes 必须给我仓库的id,但只给我null。
  • 我没有任何错误,一切似乎都正常。但是请求应该给我一个 id,它只给我 null。
  • 我不知道问题是从视图 (thymeleaf) 发送 id 还是在控制器中接收它 (spring requestParam)。并且找不到问题

标签: java spring thymeleaf


【解决方案1】:

没有表单支持对象。我使用相同的模型来获取选定的id。

在控制器中,

@RequestMapping("/productos")
public String verProductos(Model model) {
    System.out.println(almacenService.findAll());
    model.addAttribute("almacenes", almacenService.findAll());
model.addAttribute("selectedOne", new Almacen()); // newly added line
    return "productos.html";
}

@RequestMapping("/productos/selalm")
public String verProductos(@ModelAttribute @NotNull Almacen selectedOne, Model model) {//change in declaration
...
}

在 .html 文件中,修改以下行以使用模型。

<form th:action="@{/productos/selalm}" th:object="${selectedOne}" method="post">
<select class="form-control"  th:field= "*{idalmacenes}" >

尝试并反馈。

【讨论】:

  • 在这种情况下会抛出此错误:“原因:java.lang.IllegalStateException:Bean 名称 'selectedOne' 的 BindingResult 和普通目标对象都不能用作请求属性”
  • @Eduardo 您是否添加了这一行 model.addAttribute("selectedOne", new Almacen()); // 新添加的行
  • 哦,对不起,我忘记了。但是我现在已经这样做了,然后抛出了另一个错误:引起:org.springframework.beans.NotReadablePropertyException:bean类[es.eduardosarabia.weblogistics.model.Almacen]的无效属性'idalmacenes':Bean属性'idalmacenes'是不可读或有无效的getter方法:getter的返回类型是否与setter的参数类型匹配?
  • 我看到方法名称与变量不一致。能不能改一下变量名,如下试试:
  • 在这种情况下,我没有错误,但表单中的选择为空。我也将所有 id 更改为 idalmacenes,但选择仍然为空。我只能让选择正常工作,没有错误,将 th:field 放入表单中,而没有在选择中,我不知道为什么...
【解决方案2】:

控制器的实际状态是这样的:

public class MiControlador {

    @Autowired
    IProductoSERVICE productoService;
    
    @Autowired
    IAlmacenSERVICE almacenService;
    
    @Autowired
    IVentaSERVICE ventaService;
    
    @RequestMapping("/")
    public String indice() {
        return "index";
    }
    
    @RequestMapping("/login")
    public String login() {
        return "login.html";
    }
    
    @RequestMapping("/almacenes")
    public String verAlmacenes(Model model) {
        System.out.println(almacenService.findAll());
        model.addAttribute("almacenes", almacenService.findAll());
        return "almacenes.html";
    }
    @RequestMapping("/productos")
    public String verProductos(Model model) {
        System.out.println(almacenService.findAll());
        model.addAttribute("almacenes", almacenService.findAll()); // newly added line
        model.addAttribute("selectedOne", new Almacen()); // newly added line
        return "productos.html";
    }
    @RequestMapping("/productos/selalm")
    public String verProductos(@ModelAttribute @NotNull Almacen selectedOne, Model model){
        System.out.println("paso 1");
        System.out.println(selectedOne.idalmacenes);
        /*List<Producto> productos = productoService.findByAlm(idalmacenes);
        System.out.println("Paso 2");
        System.out.println(productos.toString());
        model.addAttribute("productos", productos);
        System.out.println("Paso 3");*/
        return "productos.html";
    }

以及视图的实际状态:

public class MiControlador {

    @Autowired
    IProductoSERVICE productoService;
    
    @Autowired
    IAlmacenSERVICE almacenService;
    
    @Autowired
    IVentaSERVICE ventaService;
    
    @RequestMapping("/")
    public String indice() {
        return "index";
    }
    
    @RequestMapping("/login")
    public String login() {
        return "login.html";
    }
    
    @RequestMapping("/almacenes")
    public String verAlmacenes(Model model) {
        System.out.println(almacenService.findAll());
        model.addAttribute("almacenes", almacenService.findAll());
        return "almacenes.html";
    }
    @RequestMapping("/productos")
    public String verProductos(Model model) {
        System.out.println(almacenService.findAll());
        model.addAttribute("almacenes", almacenService.findAll()); // newly added line
        model.addAttribute("selectedOne", new Almacen()); // newly added line
        return "productos.html";
    }
    @RequestMapping("/productos/selalm")
    public String verProductos(@ModelAttribute @NotNull Almacen selectedOne, Model model){
        System.out.println("paso 1");
        System.out.println(selectedOne.idalmacenes);
        /*List<Producto> productos = productoService.findByAlm(idalmacenes);
        System.out.println("Paso 2");
        System.out.println(productos.toString());
        model.addAttribute("productos", productos);
        System.out.println("Paso 3");*/
        return "productos.html";
    }

然后,抛出错误: “模板解析期间发生错误(模板:“类路径资源 [templates/productos.html]”) org.thymeleaf.exceptions.TemplateInputException:模板解析期间发生错误(模板:“类路径资源[模板/productos.html]”)“ 造成的: “原因:java.lang.IllegalStateException:Bean 名称 'selectedOne' 的 BindingResult 和普通目标对象都不能用作请求属性”

【讨论】:

    【解决方案3】:

    好的,我明白了!!! 问题是我没有将表单的名称提供给@ModelAttribute。在我阅读的许多论坛和春季指南中,这不是必需的,但似乎在这种特定情况下,这是必要的。谢谢@Niyas

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-14
      • 2014-01-02
      • 2016-01-19
      • 2014-04-18
      • 2015-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多