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

Asked

Viewed 1,026 times

1

Every time I insert one input of the kind date in my form, the server returns error 400. I have tried everything, when I remove the field date makes no mistake.

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>
  <script src="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" /> 
  • Hello, dear apprentice! I was going to welcome you, but I see you have been on the site for some time. I hope you continue to make a good use of it. There’s a vibrant programming community around here. ;)

1 answer

2


Source of the problem

This type of error is characteristic of Spring MVC and occurs when it fails to do the Binding any request data for some parameter or model.

In this case, it is because Spring MVC does not know what format is expected for the field dataNascimento of your class Usuario.

Even though I put the note @DateTimeFormat in your parameter dtNasc, Spring MVC will still try to fill the attribute of Usuario.

Simple solution, but not recommended

The simplest solution in your case would be to rename the field in your form so that Spring doesn’t try to do the Binding automatic in attribute dataNascimento.

However, I don’t recommend this because it would be unintuitive and Spring offers more than one way to solve the problem without skulking.

Set up a Property editor in the controller

Well, you must already know which fields input of the kind date send the values in the format yyyy-mm-dd, so you should report this to Spring somehow.

One of them is to configure a Property editor in its controlling 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 functional example of this in example project I have on my Github.

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

Configure the attribute in model

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

Example:

public class Usuario {

    ...

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

    ...

}
  • problem solved both with the editor Property and with the change in the model, I chose to use the editor Property. Thank you very much!

Browser other questions tagged

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