Solucionado (ver solução)
Solucionado
(ver solução)
20
respostas

PERSISTIR SEM UTILIZAR HIBERNATE

@RequestMapping("/produtos")
    public String gravar(Produto produto){
        System.out.println(produto);
        produtoDao.gravar(produto);
        return "/produtos/ok";
    }

Vocês utilizam este código para enviar os dados do formulário para a DAO. Gostaria de saber como pego os dados do formulário sem utilizar o Hibernate para pesistir no banco. Criei uma conexão com o SQL server, mas estou com dificuldades para saber como pegar os dados do formulário.

Para pegar utilizando Servlet usamos o HttpServletRequest.

20 respostas

Boa noite Daniel,

Você pode pegar os dados do formulário usando o HttpServletRequest. Ela é subinterface de ServletRequest, que contém o método getParameter(String param).

O Hibernate na verdade você usaria para, tendo já os dados vindos do teu formulário, persistí-los no SQL Server. Como você está criando a conexão na mão, pode persistir os dados manualmente, ou seja, via JDBC, usando o driver do SQL Server, escrevendo os inserts manualmente, abrindo conexão à base, executando a operação e fechando a conexão.

Espero ter ajudado. Qualquer dúvida, avisa aí.

Abraço,

Rafael.

Rafael, boa noite!

Obrigado pela resposta. Então acabei fazendo dessa forma utilizando a sub interface do ServletRequest e consequentemente o getParameter.

Eu estava pensando que daria para pegar esses dados do formulário da mesmo forma que é mostrado em aula ou de uma outra forma. Eu fiquei sem ação quando a aula chegou na parte de validar os dados do formulário, pqe eu acabei montando a aplicação de forma diferente do que é ministrado em aula. Então acabei abrindo a questão aqui o forum para ver se existia uma forma mais limpa de pegar os dados do formulário.

Rafael, vi esse exemplo e achei interessante, pois parece com o que foi passado no curso, porem não usa Hibernate. Veja se seria viável: http://www.codejava.net/frameworks/spring/spring-mvc-with-jdbctemplate-example

supondo que vc esteja usando um framework actionbasead que popule os objetos na requisição, quando vc faz:

@RequestMapping("/produtos")
    public String gravar(Produto produto){

        return "/produtos/ok";
    }

isso aqui não tem nada de Hibernate, me parece que é Spring que vc usa, então é só o Spring que popula os dados do produto com os dados oriundos do formulário, se não quiser usar hibernate, podes usar o Jdbctemplate que é um projeto da spring tbm, ou dar um jeito de injetar ou criar uma conexão jdbc normal e trabalhar com sql puro ou utilizar algum outro arcabouço jdbc como por exemplo o MyBatis que tbm tem uma integração legal com Spring

lendo mais atentamente, vejo que sseu problema não tem nada haver com hibernate e sim com o próprio spring. Vamos lá, se vc tem um produto e esse produto tem os atributos nome e preco por exemplo, quando vc submete o formulário, o próprio spring se encarrega de preencher o objeto produto.

<form:form  method="post"
                modelAttribute="produto" action="/produto">

<form:input path="name" type="text" 
                                id="nome"  />
<form:input path="preco" type="text" 
                                id="preco"  />

<button type="submit">enviar
                             </button>
</form:form>

usei tags do Spring, mas isso não importa, o importante é saber que ele vai usar o atributo name dos inputs, e vai tentar popular o objeto produto no momento do submit, então oque vc digitar no input com name="nome" ele vai tentar colocar dentro de produto.nome e assim por diante

``` @RequestMapping(value = "/produto", method = RequestMethod.POST) public String salvar(@ModelAttribute("produto") @Validated Produto produto){

Syso(produto.getNome);//o produto vai chegar aaqui carregado com os dados da requisição }

vc encontra um ótimo tutorial aqui:http://www.mkyong.com/spring-mvc/spring-mvc-form-handlingexample/

Oi Daniel,

Sim seria viável. É Spring usando JDBC. É outro modo de persistir seus dados em uma base.

As dicas do Ricardo parecem boas também. E o site do mkyong sempre tem bons exemplos. É uma ótima fonte.

Caso tenha mais duvidas, poste aí.

Caso tenha conseguido resolver o problema, pode por o post como solucionado? Assim, se mais alguém vir nossas mensagens, sabe que pode seguir o que conversamos aqui.

Abraço!

Ricardo, obrigado pela resposta. No meu formulário eu tenho um select de categorias de um produto que vem de uma entidade categoria. E na minha entidade produto eu tenho um atributo do tipo categoria. Seria viável fazer o formulário dessa forma com uma estrutura assim? Se você pode me responder seria importante pra que eu não perca muito tempo em uma questão que não que não é viável. Para pegar os dados eu uso o getParameter passo para as entidades e persisto no banco no momento funciona, mas queria ver outras formas fazer isso.

é viávél sim e muito comum também,amanhã pela manhã eu posto um código pra vc, sono tá brabo aqui

Oh agradeceria muito esse exemplo. Muito obrigado pela ajuda!!

Ricardo, boa tarde! Cara pesquisei e tentei fazer mais nunca da certo. Segue minha JSP, tentei fazer deixando apenas os atributos que vão direto para a entidade Produto. Porem não aparece nem o formulário de cadastro da erro logo na primeira linha onde tem o . O erro é :

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'produto' available as request attribute
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ 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>Mercadinho-JT - Cadastro de Produtos</title>
</head>
<body>
    <form:form id="formularioCadProdutos" action="/mercadinho-jt/produtos" method="POST" modelAttribute="produto">
        <div>
            <label>Código de Barras</label>
            <form:input type="text" id="codigoBarras" name="codigoBarras" path="codigoBarras"/>            
        </div>
        <div>
            <label>Nome Produto</label>
            <form:input type="text" id="nomeProduto" name="nomeProduto" path="nome"/>
        </div>
        <div>
            <label>Qunatidade</label>
            <form:input type="text" id="quantidade" name="quantidade" path="quantidade"/>
        </div>
        <div>
            <label>Número da Nota Fiscal</label>
            <form:input type="text" id="numeroNF" name="numeroNF" path="numeroNF"/>    
        </div>
        <div>
            <label>Preço de Compra</label>
            <form:input type="text" id="vlCompra" name="vlCompra" path="vlCompra"/>
        </div>
        <div>
            <label>Preço de Venda</label>
            <form:input type="text" id="vlVenda" name="vlVenda" path="vlVenda"/>
        </div>                
        <div>    
        <!-- MARCA É UMA ENTIDADE, E A ENTIDADE PRODUTO TEM UM ATIBUTO DO TIPO MARCA QUE RECEBE O CÓDIGO DA MARCA -->        
            <label>Marca Produto</label>
            <select id="marcaProduto" name="marcaProduto">
                <option value="">Selecione a Marca</option>
                <c:forEach items="${marcas }" var="marcas">
                    <option value="${marcas.idMarca }">${marcas.nome }</option>
                </c:forEach>                        
            </select>
        </div>    
        <div>        
        <!-- FORNECEDOR É UMA ENTIDADE, E A ENTIDADE PRODUTO TEM UM ATIBUTO DO TIPO FORNECEDOR QUE RECEBE O CÓDIGO DO FORNECEDOR -->
            <label>Forncedor</label>
            <select id="fornecedor" name="fornecedor">
                <option value="">Selecione o Fornecedor</option>
                <c:forEach items="${fornecedores }" var="fornecedor">
                    <option value="${fornecedor.id_Fornecedor }"> ${fornecedor.nome}</option>
                </c:forEach>    
            </select>    
        </div>            
        <div>
            <!-- CATEGÓRIA É UMA ENTIDADE, E A ENTIDADE PRODUTO TEM UM ATIBUTO DO TIPO CATEGÓRIA QUE RECEBE O CÓDIGO DA CATEGÓRIA -->
            <label>Categória do Produto</label>            
            <select id="categoria" name="categoria">
                <option value="">Selecione a Categória</option>
                <c:forEach items="${categorias }" var="categoria">
                    <option value="${categoria.id_Categoria }"> ${categoria.nome}</option>
                </c:forEach>    
            </select>    
        </div>            
        <button type="submit" id="btn-cadastrarProduto">Cadastrar Produto</button>
    </form:form>
</body>     
</html>

O meu Controller está assim:

@RequestMapping(method=RequestMethod.POST)
    public ModelAndView cadastrarProduto(@ModelAttribute("produto") @Validated Produto produto, BindingResult result, RedirectAttributes redirectAttributes){

        System.out.println(produto.getNome());
         if(result.hasErrors()){
                return executa();
            }
        //dao.create(produto);
        redirectAttributes.addFlashAttribute("sucesso","Produto Cadastrado Com Sucesso!!");
        return new ModelAndView("redirect:produtos");
    }

Como eu havia dito sobre a outra entidade que seria Categoria que possui na entidade Produto um atributo que uso para inserir na tabela produto no DB. Eu tenho outras duas entidades que possuem basicamente a mesma ideia onde tenho um <select que seleciono a opção e pego o código como esta demonstrado na pagina jsp. Se você puder me ajudar nessa questão, pois realmente não estou conseguindo fazer. Caso não seja possível irei ficar com a forma que já havia feito. Obrigado, agradeço desde já!!!

Boa galera!!!

Olá naquele exemplo que te passei tem como disponibilizar as listas para a view. 1- você deve colocar a lista no request, isso é feito na lógica que chama o formulario

    @RequestMapping(value = "/users/add", method = RequestMethod.GET)
    public ModelAndView showForm() {

        ModelAndView mv = new ModelAndView("/produto/formulario");
 //dao injetado com AutoWired
        List<Categoria> categorias = categoriaDao.findAll();
        mv.addAttribute("categorias", categorias);
        return mv;

    }

dessa forma essa coleção vai estar na requisição e vc vai poder iterar ela com jstl como vc fez la em cima

2-não misture a jstl com a taglib do spring, faz tudo com jstl mesmo

<form id="formularioCadProdutos" action="<c:url value="/mercadinho-jt/produtos"/"> method="POST">
        <div>
            <label>Código de Barras</label>
            <input type="text" id="codigoBarras" name="codigoBarras" />            
        </div>
        <div>
            <label>Nome Produto</label>
            <input type="text" id="nomeProduto" name="nomeProduto" />
        </div>
<!--continua o form-->
</form>

atenção, o nome dos atributos do Objeto devem coincidir com os names dos inputs, no exemplo é se se esperar que os atributos do produto sejam nomeProduto e codigoBarras

public class Produto(){

private String nomeProduto;
private String codigoBarras;
}

outro bom exemplo: http://www.edsongoncalves.com.br/2010/08/16/spring-mvc-3-na-pratica-com-jpa-2/

Preencho o <selec dessa forma:

@RequestMapping("form")
    public ModelAndView executa() throws SQLException{    

        List<Categoria> categorias = new PreencheListaComboDAO().preencheComboCategoria();
        List<Marca> marcas = new PreencheListaComboDAO().preencheComboMarcas();
        List<Fornecedor> fornecedores = new PreencheListaComboDAO().preencheComboFornecedor();

        ModelAndView modelAndView = new ModelAndView("produtos/form");    
        modelAndView.addObject("marcas", marcas);
        modelAndView.addObject("fornecedores", fornecedores);
        modelAndView.addObject("categorias", categorias);

        return modelAndView;
    }

Isso ai funciona tranquilo..

Então para pegar os dados hoje do formulário eu faço isso:

    @RequestMapping(method=RequestMethod.POST)
    public ModelAndView cadastrarProduto(HttpServletRequest req, HttpServletResponse resp, RedirectAttributes redirectAttributes) throws SQLException{
        produto = new Produto();
        produto = capturarFormularioProduto(req);    

        dao.create(produto);
        redirectAttributes.addFlashAttribute("sucesso","Produto Cadastrado Com Sucesso!!");
        return new ModelAndView("redirect:produtos");
    }
private Produto capturarFormularioProduto(HttpServletRequest req) {        
        produto = new Produto();

        Fornecedor fornecedor = new Fornecedor();
        Marca marca = new Marca();
        Categoria categoria = new Categoria();

        produto.setNome(req.getParameter("nomeProduto"));
        produto.setCodigoBarras(req.getParameter("codigoBarras"));
        produto.setNumeroNF(Integer.parseInt(req.getParameter("numeroNF")));
        produto.setQuantidade(Integer.parseInt(req.getParameter("quantidade")));

        marca.setIdMarca(Integer.parseInt(req.getParameter("marcaProduto")));
        fornecedor.setId_Fornecedor(Integer.parseInt(req.getParameter("fornecedor")));
        categoria.setId_Categoria(Integer.parseInt(req.getParameter("categoria")));

        produto.setForncedor(fornecedor);
        produto.setMarca(marca);
        produto.setCategoria(categoria);    

        return produto;
    }

O que gostaria de fazer é usar o exemplo que você deu para pegar esses dados do formulário sem ter que fazer esse código todo. Queria deixar essa captura mais elegante. Dessa forma que está funciona.

solução!

pois é Daniel, era pra funcionar

@RequestMapping(method=RequestMethod.POST)
    public ModelAndView cadastrarProduto(Produto produto) throws SQLException{

        dao.create(produto);
        redirectAttributes.addFlashAttribute("sucesso","Produto Cadastrado Com Sucesso!!");
        return new ModelAndView("redirect:produtos");
    }

a única coisa que notei é que alguns nomes de parametros que vem na requisição não coincidem com o nome dos campos do objeto produto, lembra se o produto tem um campo "nome", então o name do inputText tem que ser "nome", o teu problema certamente é esse

Ricardo, boa tarde! Cara quebrei a cabeça, mas consegui fazer como eu queria. Não sei se é uma "boa" prática, mas era assim que queria, O método ficou assim:

@RequestMapping(method=RequestMethod.POST)
    public ModelAndView cadastrarProduto(Produto produto, Preco preco, Marca marca, Fornecedor fornecedor, Categoria categoria, RedirectAttributes redirectAttributes) throws SQLException{

        produto.setMarca(marca);        
        produto.setPreco(preco);
        produto.setForncedor(fornecedor);
        produto.setCategoria(categoria);

        dao.create(produto);
        redirectAttributes.addFlashAttribute("sucesso","Produto Cadastrado Com Sucesso!!");
        return new ModelAndView("redirect:produtos");
    }

Peguei a dica que você deu a dei uma olhada em como estava as variáveis das entidades e deixei as names do form iguais. Também coloquei o método toString() nas entidades. Cara muito obrigado pelas dicas e boa vontade em ajudar. Agradeço muito, abraço!!!

Valeu Daniel, precisando é só perguntar!, só mais uma coisa pra completar, sim está correto, é a forma correta de se fazer sim,mas ainda dá pra melhorar, se produto tem um atributo marca do tipo Marca por exemplo, o atributo name do combobox poderia ficar

<select name="marca.id">

quando o spring submeter o form ele vai colocar o id da marca selecionada dentro de produto.marca.marcaId, fazendo assim para marca,preco,fornecedor e categoria, vc no exemplo acima só precisaria receber o produto e o redirectatributes pois o spring ia tratar de prhenncher o produto completo

Pohhhh! Valeu vou fazer isso, dessa forma fica muito melhor. Muito obrigado!! :D

Fiz a alteração e ficou bem melhor. Valeu pela dica. Abraços!!