繁体   English   中英

如何使用Spring和ThymeLeaf从前端正确地在后端更新对象?

[英]How to properly update an Object in the back-end from the front-end using Spring and ThymeLeaf?

我在尝试通过前端模板在后端更新我的对象时遇到了麻烦。

这是我的模板 ,它使用ThymeLeaf

    <form id="formUpdate" method="put">
        <div class="row">
            <div class="col s12">
                <h2> Modificar Gustos</h2>
            </div>
        </div>
        <div class="divider"></div>
        <div class="row">
            <label for="selectGusto">Nombre del gusto a cambiar</label>
            <select name="gustos" id="selectGusto">
                <option value="-1" selected="selected" disabled="disabled">Lista de Gustos</option>
                <option th:each="gusto : ${gustos}" th:text="${gusto.nombre}" th:value="${gusto.id}"> </option>
            </select>
        </div>
        <label for="newName">Nuevo Nombre</label>
        <input type="text" name="newName" id="newName" />
        <div class="row">
            <label for="selectCat">Elegir nueva Categoria</label>
                <select name="newCat" id="selectCat">
                    <option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
                    <option value="Dulces de Leche">Dulce de Leche</option>
                    <option value="Cremas">Cremas</option>
                    <option value="Chocolates">Chocolates</option>
                    <option value="Frutales">Frutales</option>
                </select>
        </div>
        <button type="submit" id="btn-submit" class="button">Modificar</button>
    </form>

这是我链接到模板的JS

 var newCatId;
   var idGusto;
   var newName;

   $('#selectCat').on('change', () => {
        var value = $('#selectCat').val();
        if(value === "Dulces de Leche") {
            newCatId = 1;
        }
        else if(value === "Cremas") {
            newCatId = 2;
        }
        else if(value === "Chocolates") {
            newCatId = 3;
        }
        if(value === "Frutales") {
            newCatId = 4;
        }

        console.log('newCatId: ' + newCatId);
        console.log('idGusto ' + idGusto);
        console.log('newName: ' + newName);
 });

    $('#selectGusto').on('change', function() {
    idGusto = $(this).val();
  });

    newName = $('#newName').val();

 $('#btn-submit').on('submit', (e) => {
    e.preventDefault();
    var url = idGusto + " '/edit' + '/' "+ newName + '/' + newCatId;
    $('#formUpdate').attr('action', url);
 });

这是应该处理请求的Spring 控制器

@RequestMapping(value = "/gustos/{id}/edit/{newName}/{newIdCat}")
public String updateGustoById(@PathVariable("id") int id, @PathVariable("newIdCat") int newIdCat, @PathVariable("newName") String newName){
    Gusto gusto = gustoService.findGustoById(id);
    gusto.setNombre(newName);
    gusto.setIdCategoria(newIdCat);
    gustoService.update(gusto);
    return "redirect:/gustos/edit";
}

好 !! 该代码不会在任何地方中断,但是当我单击“提交”按钮时,JS中的变量作为查询字符串在URL中移动,这不是我想要的。

单击表单的“提交”按钮后我的URL示例:

http://localhost:8080/gustos/edit?gustos=106&newName=Dulce+de+Leche+Granizado&newCat=Dulces+de+Leche

这是我第一次制作Spring App!

我的问题是,如何以正确的方式将信息发送到控制器? 如果不是这样,人们通常如何更新对象? :(

编辑 :预期的值是正常的,这意味着JS工作正常。 问题是将值发送到后端! 表单将它们作为查询字符串发送,这不是我所需要的,在查询字符串上分配的值都没有问题

在您的方案中,您尝试形成路径参数URL

1,您可以直接在表单元素中指定action属性来代替path参数

<form id="formUpdate" method="GET" action="http://localhost:8080/gustos/edit">

方法属性可以根据需要设置为GETPOST

和newCat Select框一样

 <select name="newCat" id="selectCat">
        <option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
        <option value="1">Dulce de Leche</option>
        <option value="2">Cremas</option>
        <option value="3">Chocolates</option>
        <option value="4">Frutales</option>
 </select>

在后端,您可以使用@RequestParam获取参数值

@RequestMapping(value = "/gustos/edit")
public String updateGustoById(@RequestParam(value="gustos") int id, @RequestParam(value="newCat") 
int newIdCat, @RequestParam(value="newName") String newName)
{
  Gusto gusto = gustoService.findGustoById(id);
  gusto.setNombre(newName);
  gusto.setIdCategoria(newIdCat);
  gustoService.update(gusto);
  return "redirect:/gustos/edit";
}

2.另一种方法,构造一个带有表单字段值JSON字符串(就像您对路径参数所做的一样),在提交表单时,通过ajax调用将此JSON字符串发送到后端。 在服务层上,将此JSON字符串保留为Java Bean (如果Bean结构与JSON匹配,Spring Boot将通过@RequestBody批注将JSON值与Bean字段绑定)。

我建议您在表单中使用th:object 提交表单时,这会立即创建给定类型的对象。 因此,假设您的对象是Gusto类型。 如果要从头开始创建新实体,可以在控制器中添加此方法,该方法将返回Gusto类型的新实体。

新模型属性

// In order to use th:object in a form, we must be able to map a new entity to that form.
// In this case we return a Gusto entity.
@ModelAttribute(value = "newGusto")
public Gusto newGusto() {return new Gusto();}

形成

因此,现在,您可以使用th:object="${newGusto}"在表单中使用此实体。 这将为您创建一个新实体,您可以将字段映射到该实体。

为此,您需要在表单中添加以下一个元素。

<form action="/gustos/edit/" id="formUpdate" method="put" th:object="${newGusto}">
    <div class="row">
        <div class="col s12">
            <h2> Modificar Gustos</h2>
        </div>
    </div>
    <div class="divider"></div>
    <div class="row">
        <label for="selectGusto">Nombre del gusto a cambiar</label>
        <select th:field="*{id}" name="gustos" id="selectGusto">
            <option value="-1" selected="selected" disabled="disabled">Lista de Gustos</option>
            <option th:each="gusto : ${gustos}" th:text="${gusto.nombre}" th:value="${gusto.id}"> </option>
        </select>
    </div>
    <label for="newName">Nuevo Nombre</label>
    <input th:field=*{nombre} type="text" name="newName" id="newName" />
    <div class="row">
        <label for="selectCat">Elegir nueva Categoria</label>
            <select th:field="*{categoria} name="newCat" id="selectCat">
                <option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
                <option value="Dulces de Leche">Dulce de Leche</option>
                <option value="Cremas">Cremas</option>
                <option value="Chocolates">Chocolates</option>
                <option value="Frutales">Frutales</option>
            </select>
    </div>
    <button type="submit" id="btn-submit" class="button">Modificar</button>
</form>

与当前代码唯一的区别是在选择和输入中添加了th:field元素以及th:object 这些输入和选择中的每一个都会自动将每个字段映射到您刚刚在表单中创建的新实体。

调节器

现在,对于您的控制器,您需要对其进行以下更改。

@RequestMapping(value = "/gustos/edit/")
public String updateGusto(@ModelAttribute("newGusto") Gusto gustoToUpdate){
    Gusto gusto = gustoService.findGustoById(gustoToUpdate.getId());
    gusto.setNombre(gustoToUpdate.getNombre());
    gusto.setIdCategoria(gustoToUpdate.getCategoria());
    gustoService.update(gusto);
    return "redirect:/gustos/edit";
}

当然,就您而言,更改jquery很重要。 我们现在不想更改URL。 我们只想提交表格。 因此,以下代码将必须删除。

$('#btn-submit').on('submit', (e) => {
    e.preventDefault();
    var url = idGusto + " '/edit' + '/' "+ newName + '/' + newCatId;
    $('#formUpdate').attr('action', url);
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM