Problem when passing polluted bean to controller and insert in BD using Java with Spring mvc

Asked

Viewed 1,318 times

2

I wish you could help me with this problem that is occurring in my application.

Below is the code:

 package br.com.estoque.Controller;


 import java.util.Map;

 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.ui.ModelMap;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.ModelAttribute;
 import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import br.com.estoque.Dao.CategoriaProdutoDao;
import br.com.estoque.Dao.ProdutoDao;
import br.com.estoque.Modelo.Produto;

@Controller
public class ProdutoController {

@RequestMapping("produtoForm")
public ModelAndView entradaForm(){
    ModelAndView mav = new ModelAndView();
    CategoriaProdutoDao dao = new CategoriaProdutoDao();
    mav.setViewName("produtos/frmCadastroProduto");
    mav.addObject("lista",dao.listar());
    mav.addObject("produto",new Produto());
    return mav;

}

@RequestMapping(value = "/inserirProduto", method = RequestMethod.POST)
public String save(@ModelAttribute("produto") Produto produto){
    ProdutoDao dao = new ProdutoDao();      
    dao.adiciona(produto);
    return "produtos/frmCadastroProduto";
}


}

My frmCadastroProduct

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>   
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Registration</title>
</head>
<body>
    <div align="center">
        <form:form action="inserirProduto" method="post" modelAttribute="produto">

            <table border="0">   

            <tr>
        <td><form:label path="descricao">Nome Produto</form:label></td>
        <td><form:input path="descricao" /></td>
    </tr>
    <tr>
        <td><form:label path="categoriaProduto">Selecione a categoria de produto</form:label></td>
        <td><form:select path="categoriaProduto">
            <form:option value=" - " label="--Please Select"></form:option>
            <form:options items="${lista}" itemValue="cdCategoriaProduto" itemLabel="descricao"/>
        </form:select>
        </td>
    </tr>


                <tr>
                    <td colspan="2" align="center"><input type="submit" value="Register" /></td>
                </tr>
            </table>


        </form:form>
    </div>
</body>
</html>

Error screen that is turning me...

inserir a descrição da imagem aqui

  • Luiz, welcome to [en.so]! What is the URL of error 400?

  • http://localhost:8080/Stock/inProduct is this one! , if you need more details to understand the problem I command!!

  • I compared to a system I have here and apparently everything is right, except that I can not check your settings. It even runs the method inserirProduto()? If you go through there, the problem is probably in the redirect at the end. You tme a Tiles configured to ok?

  • And remove that note @ResponseBody, it is usually used to return Json. You have another record that works with POST?

  • I’ve already removed @ResponseBody , I do own a JSP called ok. Method adds() does not get to be executed, as it does not return an msg in the console I put in the execution of the method. If you need more information about my settings I can post here!! I’m a little desperate because I need to deliver this system by the end of the year, and this is just the first screen of registration... thanks for the help!!!

  • if Voce can pass me as the controller of this your system you compared was, it would be of great help too!

Show 1 more comment

2 answers

3


The problem seems to be caused because you have a "complex type" CategoriaProduto as an attribute of Produtobeing mapped to a simple value field, i.e., the"combo" whose option value is based cdCategoriaProduto.

I understood that from the excerpt produto.getCategoriaProduto().getCdCategoriaProduto().

Unless you’ve set up a Binder somewhere else, Spring will see that the information submitted in the request is not compatible with your model received per parameter, then explaining the 400 error that the request is syntactically incorrect.

What is the solution?

1. Use an attribute "Simple"

Create an attribute codigoCategoria of type String or numeric to receive the form value instead of using a class from you.

If you need to retrieve other category information, use the code to retrieve session or database value.

2. Create a Publisher

Spring allows you to configure a special class to auto-convert during Binding of request with his model.

Take an example (that I took from Soen):

public class GroupEditor extends PropertyEditorSupport{

    private final GroupService groupService;

    public GroupEditor(GroupService groupService){
        this.groupService= groupService;
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
      Group group = groupService.getById(Integer.parseInt(text));
      setValue(group);
    }
}

The method setAsText is used during the request. It will receive the value of the field (the code, in your case) and then you must recover the object CategoriaProduto correspondent.

Note that this groupService example would be a bean responsible for fetching the value in the database, for example.

Finally, you configure Spring to use the above class in your Controller as follows:

@InitBinder
protected void initBinder(WebDataBinder binder)     {
      binder.registerCustomEditor(Group.class, new GroupEditor(groupService));
}

Make an adaptation of this code to your classes.

  • Could Voce explain to me better the option number 1 of how to solve the problem... I changed my controller in relation to how I am disabling my models for JSP, but I did not understand where to create the variable string so that the error does not occur. Thank you utluiz

  • @Luizfernandoaugusto Change the type of attribute of CategoriaProduto for a String. Then Spring will be able to fill in the code. Then if you need other product data, you can recover it again from the database. This is the simplest solution to do and explain.

  • 1

    I managed to create the publishing class!! I solved this problem Thank you!

0

This is your way

@RequestMapping(value = "/inserirProduto", method = RequestMethod.POST)
public String save(@ModelAttribute("produto") Produto produto){
//sua logica aqui
}

Note that you are sent via post, so it should be like this:

@RequestMapping(value = {"/inserirProduto,""}, method = RequestMethod.POST)
public String save(@RequestBody Produto produto){
// sua logica aqu
}

When it comes to screen the popular spring for you, as you are using post then have to use @RequestBody, also note the use of {} in the @RequestMapping.

So it will work properly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.