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

Minhas validacoes nao aparecem!

Ola pessoal, estou parado na parte de Validacoes do curso de SpringMVC, o problema é que minhas validacoes simplesmente nao aparecem. Segui ao pe da letra o que o instrutor fez no video e mesmo assim, nao aparecem as mensagens do arquivo messages.properties. As mensagens deveriam aparecer ao tentar cadastrar um livro sem algum dos campos preenchidos, mas nenhuma aparece. Meu form:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Livros de tecnologia e muito mais</title>
</head>
<body>
    <form:form action="${s.mvcUrl('PC#gravar').build() }" method="post"
        commandName="produto">
        <div>
            <label>Titulo:</label>
            <input type="text" name="titulo"> <br>
            <form:errors path="titulo" />
        </div>
        <div>
            <label>Descricao:</label>
            <textarea rows="10" cols="20" name="descricao"></textarea>
            <form:errors path="descricao" />
            <br>
        </div>
        <div>
            <label>Paginas</label> <input type="number" name="paginas">
            <form:errors path="paginas" />
            <br>

        </div>

        <c:forEach items="${tipos }" var="tipoPreco" varStatus="status">
            <label>${tipoPreco }</label>
            <input type="text" name="precos[${status.index }].valor">
            <input type="hidden" name="precos[${status.index }].tipo"
                value="${tipoPreco }">
        </c:forEach>
        <button type="submit">Cadastrar</button>
    </form:form>
</body>
</html>

messages.properties

field.required = Campo obrigatório
field.required.produto.titulo = Campo titulo obrigatorio
field.required.produto.descricao = Campo descricao obrigatorio
field.required.produto.paginas = Campo paginas obrigatorio
typeMismatch = Tipo do dado invalido

AppWebConfiguration:

package org.casadocodigo.loja.conf;

import org.casadocodigo.loja.controllers.HomeController;
import org.casadocodigo.loja.controllers.ProdutosController;
import org.casadocodigo.loja.daos.ProdutoDAO;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@EnableWebMvc
@ComponentScan(basePackageClasses = { HomeController.class, 
                                        ProdutosController.class,
                                      ProdutoDAO.class})
public class AppWebConfiguration {

    @Bean
    public InternalResourceViewResolver configuraViews() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
    //metodo responsavel por encontrar 
    //o arquivo message.properties dentro do web-inf
    @Bean
    public MessageSource messageSource(){
        ReloadableResourceBundleMessageSource messageSource 
        = new ReloadableResourceBundleMessageSource();

        messageSource.setBasename("/WEB-INF/messages");
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setCacheSeconds(1);

        return messageSource;
    }
}
7 respostas

Gustavo, tudo bem ?

Tive um problema similar, mas o meu por algum motivo não estava sendo interpretado como properties, ele parece uma string ou um arquivo de marcação ?

E como voce resolveu Matheus, no meu caso o messages.properties é exatamente esse que eu postei ai acima. Coloquei ele dentro da pasta WEB-INF. Coloquei as validacoes da forma como foi mostrado dentro da classe ProdutoValidation

package org.casadocodigo.loja.validation;

import org.casadocodigo.loja.models.Produto;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class ProdutoValidation implements Validator {
    // classe a qual a validacao dara suporte
    @Override
    public boolean supports(Class<?> clazz) {
        return Produto.class.isAssignableFrom(clazz);
    }

    // efetiva a validacao
    @Override
    public void validate(Object target, Errors errors) {
        ValidationUtils.rejectIfEmpty(errors, "titulo", "field.required");
        ValidationUtils.rejectIfEmpty(errors, "descricao", "field.required");
        Produto produto = (Produto) target;
        if (produto.getPaginas() <= 0) {
            errors.rejectValue("paginas", "field.required");
        }
    }

}

ProdutosController

package org.casadocodigo.loja.controllers;

import java.util.List;

import javax.validation.Valid;

import org.casadocodigo.loja.daos.ProdutoDAO;
import org.casadocodigo.loja.models.Produto;
import org.casadocodigo.loja.models.TipoPreco;
import org.casadocodigo.loja.validation.ProdutoValidation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
@RequestMapping("/produtos")
public class ProdutosController {

    @Autowired
    private ProdutoDAO produtoDao;

     //vincula o validador com o controller
    @InitBinder
    public void initBinder(WebDataBinder binder){
        binder.addValidators(new ProdutoValidation());
    }

    @RequestMapping("/form")
    public ModelAndView form(Produto produto) {
        /*
         * modelAndView Envia objetos da Model para a View 
         * e  tambem retorna
         * o caminho da view no construtor
         */
        ModelAndView modelAndView = new ModelAndView("produtos/form");
        modelAndView.addObject("tipos", TipoPreco.values());
        System.out.println("Entrando no formulario");
        return modelAndView;


    }

    @RequestMapping(method=RequestMethod.POST)
    public ModelAndView gravar(@Valid Produto produto, BindingResult result, RedirectAttributes ra){
        if(result.hasErrors()){
            return form(produto);
        }
        produtoDao.gravar(produto);
        ra.addFlashAttribute("sucesso", "Produto cadastrado com sucesso!");
        return new ModelAndView("redirect:produtos");
    }

    @RequestMapping(method=RequestMethod.GET)
    public ModelAndView listar(){
        List<Produto> produtos= produtoDao.listar();
        ModelAndView modelAndView = new ModelAndView("produtos/lista");
        modelAndView.addObject("produtos", produtos);
        return modelAndView;
    }
}

Nao aparece nenhuma mensagem de validacao na hora de cadastrar um produto, sera que so eu estou tendo esse problema?

Gustavo,

Te fiz uma pergunta ali em cima, rs

Cara, consegue me mostrar um print da seu arquivo application.properties

Matheus, nesse projeto nao tem esse arquivo application.properties, pelo menos nao na parte em que estou.

solução!

Encontrei o problema, tinha um erro na url da action do formulário no lugar de dois pontos coloquei apenas um. Simplesmente ridículo! Odeio o spring framework kk.

O engracado e que das duas formas funcionaram na hora de subir o codigo para o Tomcat:

Como estava:

<form:form action="${s.mvcUrl('PC#gravar').build() }" method="post"
        commandName="produto">

Como deveria estar:

<form:form action="${s:mvcUrl('PC#gravar').build() }" method="post"
        commandName="produto">

Apenas isso!

Boa ! :D