Input Date causes error 400 - The request sent by the client was syntactically incorrect

1

Every time I enter a input of type date in my form , the server returns error 400. I've tried everything, when I remove the field date does not give the error.

My controller:

package br.com.starcode.agenda.controller;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import br.com.starcode.agenda.domain.Usuario;
import br.com.starcode.agenda.service.UsuarioService;

@Controller
public class UsuarioController {

    @Autowired
    UsuarioService UsuarioService; 

    @RequestMapping(value="/usuario", params="new")
    ModelAndView novoUsuario() {
        Usuario usuario = new Usuario();
        usuario.setDataNascimento(new Date());
        return new ModelAndView("cadastrar-usuario")
                .addObject("usuario", usuario);
    }

    @RequestMapping(value="/usuario", method = RequestMethod.POST)
    ModelAndView confirmarNovo(
            Usuario novoUsuario,
            @RequestParam(value="dataNascimento", required=false) @DateTimeFormat(pattern="yyyy-MM-dd") Date dtNasc,
            RedirectAttributes redirectAttributes) {
        try {
            novoUsuario.setDataNascimento(dtNasc);
            //insert 
            UsuarioService.insert(novoUsuario);
            //success
            redirectAttributes.addFlashAttribute("msg", "Registro '" + novoUsuario.getIdUsuario() + "' inserido com sucesso!");
            return new ModelAndView("redirect:/");
        } catch (Exception e) {
            return new ModelAndView("cadastrar-usuario")
                    .addObject("erro", e.getMessage())
                    .addObject("usuario", novoUsuario);
        }
    }

}

And the JSP:

<%@ 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>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Coleções - Cadastrar Usuário</title>

<!-- Bootstrap -->
<link href="<c:url value="/bootstrap/css/bootstrap.min.css" />" rel="stylesheet">
<link href="<c:url value="/bootstrap/css/bootstrap-responsive.css" />" rel="stylesheet">

<style type="text/css">
  body {
    padding-top: 40px;
    padding-bottom: 40px;
    background-image: url(img/album-covers.jpg);
  }

  .form-signin {
    max-width: 600px;
    padding: 19px 29px 29px;
    margin: 0 auto 20px;
    background-color: #fff;
    border: 1px solid #e5e5e5;
    -webkit-border-radius: 5px;
       -moz-border-radius: 5px;
            border-radius: 5px;
    -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05);
       -moz-box-shadow: 0 1px 2px rgba(0,0,0,.05);
            box-shadow: 0 1px 2px rgba(0,0,0,.05);
  }

  .container {
    max-width: 650px;
    padding: 10px;
  }

</style>

<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script><scriptsrc="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>

<div class="container" style="background-color:#ffffff" >

            <h1>Cadastrar Usuário</h1>
            <p>Faça seu cadastro abaixo e monte já suas coleções!</p>

                    <form id="form-cadastrar-usuario" class="form-horizontal" role="form" method="post" action="<c:url value="/usuario" />" >


                        <div class="input-group input-group-lg">
                            <span class="input-group-addon">Nome:</span>
                            <input type="text" class="form-control" placeholder="Digite seu nome" name="nomeUsuario" id="nomeUsuario" value="${usuario.nomeUsuario}" >
                        </div><p/>

                        <div class="input-group input-group-lg">
                            <span class="input-group-addon">E-mail:</span>
                            <input type="text" class="form-control" placeholder="Digite seu e-mail" name="emailUsuario" id="emailUsuario" value="${usuario.emailUsuario}" >
                        </div><p/>

                        <div class="input-group input-group-lg">
                            <span class="input-group-addon">Sobrenome:</span>
                            <input type="text" class="form-control" placeholder="Digite seu sobrenome" name="sobrenomeUsuario" id="sobrenomeUsuario" value="${usuario.sobrenomeUsuario}" >
                        </div><p/>

                        <div class="input-group input-group-lg">
                            <span class="input-group-addon">Senha:</span>
                            <input type="password" class="form-control" placeholder="Digite uma senha" name="senhaUsuario" id="senhaUsuario" value="${usuario.senhaUsuario}" >
                        </div><p/>

                        <div class="input-group input-group-lg">
                            <span class="input-group-addon">Data de Nascimento:</span>
                            <input type="date" class="form-control" placeholder="Digite a data do seu nascimento" name="dataNascimento" id="dataNascimento" value="<fmt:formatDate pattern="yyyy-MM-dd" value="${usuario.dataNascimento}" />" />
                        </div><p/>

                        <br>

                        <button type="submit" class="btn btn-large btn-primary" >Enviar</button>
                        <button type="reset" class="btn btn-large btn-primary" >Limpar</button>
                        <a href="<c:url value="/" />" class="btn btn-large btn-danger" >Cancelar</a>

                    </form>             

    </div>

        <!-- MENSAGENS -->
<div class="container-fluid">

  <c:if test="${not empty param.erro or not empty erro}">
  <div class="alert alert-danger fade in text-center" role="alert">
    <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Fechar</span></button>
    <strong>${param.erro}${erro}</strong>
  </div>
  </c:if>
  <c:if test="${not empty param.msg or not empty msg}">
  <div class="alert alert-success fade in text-center" role="alert">
    <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Fechar</span></button>
    <strong>${param.msg}${msg}</strong>
  </div>
  </c:if>

</div>


<jsp:include page="template-footer.jsp" /> 
    
asked by anonymous 23.11.2014 / 16:46

1 answer

2

Origin of the problem

This type of error is characteristic of Spring MVC and occurs when it can not bind some request data to some parameter or model .

>

In this case, Spring MVC does not know the expected format for the dataNascimento field of its Usuario class.

Even if you put the @DateTimeFormat annotation in your dtNasc parameter, Spring MVC will still try to fill the Usuario attribute.

Simple but not recommended solution

The simplest solution in your case would be to change the field name on your form so Spring does not try to auto in the dataNascimento attribute.

However, I do not recommend this because it would be impractical and Spring offers more than one way to solve the problem without any hassle.

Configure a property editor in controller

Well, you should know that input fields of type date send the values in yyyy-mm-dd format, so you should tell Spring that in some way.

One of these is to set up a property editor in your controller class.

Example:

@InitBinder
void initBinder(WebDataBinder webDataBinder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    dateFormat.setLenient(false);
    webDataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}

There is a working example of this in example project I have in my GitHub .

Note that the above method affects the date interpretation for all controller requests.

Configure the attribute in model

The problem would also be solved by annotating the dataNascimento attribute in your model class with the @DateTimeFormat annotation.

Example:

public class Usuario {

    ...

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date dataNascimento;

    ...

}
    
23.11.2014 / 23:32