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

Validation n está funcionando corretamente

Olá. Estou encontrando um problema quando vou cadastrar um objeto no meu formulário. Mesmo eu preenchendo os 4 campos necessários para o cadastro do objeto, a minha validation class continua n permitindo que o cadastro fosse concluido. Vou compartilhar os códigos:

Como pode ver, são 4 campos requeridos:

public class VisitanteValidation implements Validator{

    @Override
    public boolean supports(Class<?> clazz) {
        return Visitante.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        ValidationUtils.rejectIfEmpty(errors, "nome", "field.required");
        ValidationUtils.rejectIfEmpty(errors, "documento", "field.required");
        ValidationUtils.rejectIfEmpty(errors, "placa", "field.required");
        ValidationUtils.rejectIfEmpty(errors, "destino", "field.required");
    }

}

Método do controller:

    @RequestMapping(method=RequestMethod.POST)
    public ModelAndView grava(MultipartFile fotoPath, @Valid Visitante visitante, BindingResult result, RedirectAttributes redirectAttributes) {

        if(result.hasErrors()){
            System.out.println("TEM ERRO");
            return form(visitante);
        }

        visitante.setDataHora(Calendar.getInstance());

        if (fotoPath != null && !fotoPath.getOriginalFilename().isEmpty()) {
            String path = fileSaver.write("fotosPasta", fotoPath);
            visitante.setfotoPath(path);
        }

        visitanteDao.gravar(visitante);
        redirectAttributes.addFlashAttribute("sucesso", "Visitante Cadastrado com Sucesso");
        return new ModelAndView("redirect:/visitantes");
    }

E o form:

<div class="container">
    <h1>Cadastro de Visitantes</h1>
    <form:form action="${s:mvcUrl('VC#grava').build() }" method="POST"
        modelAttribute="visitante" enctype="multipart/form-data">
        <%--modelAttribute = novo commandName  --%>
        <div class="form-group">
            <label>Nome</label>
            <form:input path="nome" cssClass="form-control" />
            <form:errors path="nome" />
        </div>
        <div class="form-group">
            <label>Documento</label>
            <form:input path="documento" cssClass="form-control" />
            <form:errors path="documento" />
        </div>
        <div class="form-group">
            <label>Placa do Veículo</label>
            <form:input path="placa" cssClass="form-control" />
            <form:errors path="placa" />
        </div>
        <div class="form-group">
            <label>Destino de Visita</label>
            <form:input path="destino" cssClass="form-control" />
            <form:errors path="destino" />
        </div>
        <div class="form-group">
            <label>Foto</label><input type="file" name="fotoPath"
                class="form-control" />
        </div>
        <button type="submit" class="btn btn-primary">Cadastrar</button>
    </form:form>
</div>

Como eu disse anteriormente, mesmo preenchendo os 4 campos necessários pelo validation, ele ainda retorna p lista.

7 respostas

Boa noite, Felipe! Como vai?

Vc tbm precisa implementar o método initBinder() no seu controlador! Vc fez isso?

@InitBinder
public void InitBinder(WebDataBinder binder){
    binder.addValidators(new VisitanteValidation());
}

Sim.

[...]
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.addValidators(new VisitanteValidation());        
    }
[...]

Uma coisa, Felipe! Vc disse que "como eu disse anteriormente, mesmo preenchendo os 4 campos necessários pelo validation, ele ainda retorna p lista."

Pergunta: mas retornar para a lista de visitantes é exatamente o que vc quer fazer quando o preenchimento está correto, não? Se sim, então o sistema está se comportando corretamente.

Concordo, está se comportando corretamente neste sentido. Porém mesmo eu completando todos os campos requisitados ele ainda continua me impedindo de cadastrar um novo objeto. Lendo a documentação do Errors.class, inseri "result.getAllErrors())" no meu método para tentar rastrear a raiz do problema. Me deparei com:

[Field error in object 'visitante' on field 'fotoPath': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@4502e3e9]; codes [typeMismatch.visitante.fotoPath,typeMismatch.fotoPath,typeMismatch.java.lang.String,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [visitante.fotoPath,fotoPath]; arguments []; default message [fotoPath]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.String' for property 'fotoPath'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.String' for property 'fotoPath': no matching editors or conversion strategy found]]

Pelo q estou pesquisando, parece ser algo referente com a repetição da variável "fotoPath", estou tentando mudar algumas coisas mas ainda n consegui resolver.

Identifiquei no forum, uma ocorrência semelhante: https://cursos.alura.com.br/forum/topico-spring-nao-converte-multipartfile-para-string-43845

solução!

Eis que vos trago boas notícias! Dei uma pesquisada no Google e ele me retornou esse link aqui do fórum mesmo com alguém que já teve esse mesmo problema!

Dá uma olhada lá e vê se resolve o seu problema tbm!

Dica: Em vez de mudar o seu modelo como foi dito no tópico do link, sugiro que vc troque o name do campo de foto no seu formulário e o nome do parâmetro que recebe a foto na sua action para deixar a solução mais simples!

Faça algo assim:

No formulário

<input type="file" name="pathFoto"
                class="form-control" />

Na action

public ModelAndView grava(MultipartFile pathFoto, @Valid Visitante visitante, BindingResult result, RedirectAttributes redirectAttributes) {
     // restante do código...
}

Kkkkkkk. Funcionou, Gabriel. Assim q vc respondeu, eu havia conseguido utilizando :

if (result.hasErrors() && (result.getErrorCount() > 1 || !result.hasFieldErrors("fotoPath"))) {
            if (result.hasErrors()) {
                System.out.println("getAllErrors " + result.getAllErrors());
                return form(visitante);
            }
        }

Mas logo testei a sua sugestão, e do jeito que vc sugeriu ficou muito melhor. Obrigado, Gabriel. Ótima noite.

AÊ! Mto bem, Felipe!

Uma ótima noite pra vc tbm!

Grande abraço e bons estudos!