0

My web app is basically: jsp + angularjs, but this datepicker is running with jQuery because of the template I am using.

Before explaining what is happening, my DTO's attributes matches my entity attributes, both java.util.Date, I am just informing that I already verified the attributes type because I got many 400 bad requests because of that.

enter image description here

I have a modal where I have many fields, but I inserted recently two datepickers (bootstrap) and till then app is crashing, when I send the POST via ajax to my java controller, I am receiving a bad request (400), I think that it is because the format is wrong (mm/dd/yyyy). I formatted correctly the date to pt_BR for Brazil but it is not working.

BoxApp.controller("UsuariosController", function($scope, $http) { 
 
 $scope.usuarios={};
 $scope.usuariosParaAlterar={};
 
 $scope.iniciar = function() {
  $http.get('/boxmlV2/usuario').success(function (response) {
   $scope.usuarios = response;
  });
 };
 $scope.iniciar();
 
 $scope.setSelected = function(selecao){
  $scope.usuariosParaAlterar = selecao;
 };
 
 /**
  * Trecho para validar o form ao submeter.
  */
 $scope.submitted = false;
 $scope.submitForm = function(formUsuarios) {
     $scope.submitted = true;     

  if (formUsuarios.$valid) {
   $("#dataValidadeConta").datepicker({
       format: 'dd/mm/yyyy',                
       language: 'pt-BR'
   });
            $("#dataValidadeSenha").datepicker({
                format: 'dd/mm/yyyy',                
                language: 'pt-BR'
            });       
   
   $scope.editaUsuario();
  }
 };
 
 $scope.editaUsuario = function() {  

  $http.post('/boxmlV2/usuario/salvarUsuario', {
   ativo : $scope.usuariosParaAlterar.ativo, 
   idUsuario : idUsuario.value,
   nome : nome.value,
   senha : senha.value,
   email : email.value,
   bloqueado : $scope.usuariosParaAlterar.bloqueado,
   dataValidadeConta : $scope.usuariosParaAlterar.dataValidadeConta,
   dataValidadeSenha : $scope.usuariosParaAlterar.dataValidadeSenha, 
   resetSenha : $scope.usuariosParaAlterar.resetSenha,
   perfil : $scope.usuariosParaAlterar.perfil   
  }).then(function(response) {
   $scope.sucesso();
  }, function(response) {
   // called asynchronously if an error occurs
   // or server returns response with an error status.
  });

 };

 $scope.sucesso = function() {
  $scope.closeMyPopup();
  $scope.iniciar();  
 };

 $scope.closeMyPopup = function() {
  $(myModal_autocomplete).modal('hide');
 };
 
 $scope.preparaInsercao = function() {  
  nome.value = "";
  senha.value = "";
  email.value = "";  
  $(idUsuario).val("");
  $(idUsuario).hide();
  $(idLabel).hide();
 }; 
 
});
<!-- START MODAL -->
     <div id="myModal_autocomplete" class="modal fade" role="dialog"
      aria-hidden="true" style="display: none;">
      <div class="modal-dialog">
       <div class="modal-content">
        <div class="modal-header">
         <button type="button" class="close" data-dismiss="modal"
          aria-hidden="true"></button>
         <h4 class="modal-title">Cadastro de Usuário</h4>
        </div>
        <div class="modal-body form">
         <form name="form" id="form_sample_2" role="form"
          class="form-horizontal ng-pristine ng-valid" novalidate>

          <div class="form-body">
           <div class="form-group">
            <label class="control-label col-md-3">Ativo:<span
             class="required" aria-required="true"> * </span></label>
            <div class="col-md-9">
             <div class="clearfix">
              <div>
               <label class="btn btn-default active"> <input
                type="radio" name="ativo"
                ng-model="usuariosParaAlterar.ativo" value="true">
                Sim <br />
               </label> <label class="btn btn-default"> <input
                type="radio" name="ativo"
                ng-model="usuariosParaAlterar.ativo" value="false">
                Não <br />
               </label>
              </div>
             </div>
            </div>
           </div>

           <div class="form-group">
            <label class="control-label col-md-3">Nome:<span
             class="required" aria-required="true"> * </span></label>
            <div class="col-md-9">
             <input type="text" ng-model="usuariosParaAlterar.nome"
              class="form-control" id="nome" maxlength="100" name="nome"
              required> <span style="color: red"
              ng-show="submitted && form.nome.$error.required">Campo
              Nome Obrigatório.</span>
            </div>
           </div>

           <div class="form-group">
            <label class="control-label col-md-3">Senha:<span
             class="required" aria-required="true"> * </span></label>
            <div class="col-md-9">
             <input type="password" ng-model="usuariosParaAlterar.senha"
              class="form-control" maxlength="100" name="senha"
              placeholder="Do E-mail De Recebimento do XML" id="senha"
              required> <span style="color: red"
              ng-show="submitted && form.senha.$error.required">Campo
              Senha Obrigatório.</span>
            </div>
           </div>

           <div class="form-group">
            <label class="control-label col-md-3">E-mail:<span
             class="required" aria-required="true"> * </span></label>
            <div class="col-md-9">
             <input type="email" ng-model="usuariosParaAlterar.email"
              class="form-control" id="email" maxlength="100"
              name="email" required> <span style="color: red"
              ng-show="submitted && form.email.$error.required">Campo
              E-mail Obrigatório.</span>
            </div>
           </div>

           <div class="form-group">
            <label class="control-label col-md-3">Bloqueado:<span
             class="required" aria-required="true"> * </span></label>
            <div class="col-md-9">
             <div class="clearfix">
              <div>
               <label class="btn btn-default active"> <input
                type="radio" name="bloqueado"
                ng-model="usuariosParaAlterar.bloqueado" value="true">
                Sim <br />
               </label> <label class="btn btn-default"> <input
                type="radio" name="bloqueado"
                ng-model="usuariosParaAlterar.bloqueado" value="false">
                Não <br />
               </label>
              </div>
             </div>
            </div>
           </div>

           <div class="form-group">
            <label class="control-label col-md-3">Data Validade Conta:<span
             class="required" aria-required="true"> * </span></label>
            <div class="col-md-9">
             <input
              class="form-control form-control-inline input-medium date-picker"
              name="dataValidadeConta" id="dataValidadeConta" 
              ng-model="usuariosParaAlterar.dataValidadeConta"
              size="16" type="text" value="" required/> <span
              class="help-block"> Selecione a data </span>
              <span style="color: red"
              ng-show="submitted && form.dataValidadeConta.$error.required">Campo
              Data Validade Conta Obrigatório.</span>            
            </div>
           </div>

           <div class="form-group">
            <label class="control-label col-md-3">Data Validade Senha:<span
             class="required" aria-required="true"> * </span></label>
            <div class="col-md-9">
             <input
              class="form-control form-control-inline input-medium date-picker"
              ng-model="usuariosParaAlterar.dataValidadeSenha"
              name="dataValidadeSenha" id="dataValidadeSenha" 
              size="16" type="text" value="" required/> <span
              class="help-block"> Selecione a data </span>
              <span style="color: red"
              ng-show="submitted && form.dataValidadeSenha.$error.required">Campo
              Data Validade Senha Obrigatório.</span>            
            </div>
           </div>

           <div class="form-group">
            <label class="control-label col-md-3">Resetar Senha:<span
             class="required" aria-required="true"> * </span>
            </label>
            <div class="col-md-9">
             <div class="clearfix">
              <div>
               <label class="btn btn-default active"> <input
                type="radio" name="resetSenha"
                ng-model="usuariosParaAlterar.resetSenha" value="true">
                Sim <br />
               </label> <label class="btn btn-default"> <input
                type="radio" name="resetSenha"
                ng-model="usuariosParaAlterar.resetSenha" value="false">
                Não <br />
               </label>
              </div>
             </div>
            </div>
           </div>

           <div class="form-group">
            <label class="control-label col-md-3">Perfil
             Usuário:<span class="required" aria-required="true">
              * </span>
            </label>
            <div class="col-md-9">
             <div class="clearfix">
              <div>
               <label class="btn btn-default active"> <input
                type="radio" name="perfil"
                ng-model="usuariosParaAlterar.perfil" value="true">
                Admin <br />
               </label> <label class="btn btn-default"> <input
                type="radio" name="perfil"
                ng-model="usuariosParaAlterar.perfil" value="false">
                Usuário <br />
               </label>
              </div>
             </div>
            </div>
           </div>

           <div class="form-group">
            <label id="idLabel" class="control-label col-md-3">ID:<span
             class="required" aria-required="true"> * </span></label>
            <div class="col-md-9">
             <input type="text" ng-model="usuariosParaAlterar.idUsuario"
              class="form-control" id="idUsuario" maxlength="100"
              name="idUsuario" required disabled> <span
              style="color: red"
              ng-show="submitted && form.idUsuario.$error.required">Campo
              ID Obrigatório.</span>
            </div>
           </div>
          </div>
         </form>
        </div>
        <div class="modal-footer">
         <button type="button" class="btn btn-default"
          data-dismiss="modal">Cancelar</button>
         <button type="submit" class="btn btn-primary"
          ng-click="submitForm(form)">
          <i class="fa fa-check"></i> Salvar
         </button>
        </div>
       </div>
      </div>
     </div>
     <!-- END MODAL -->

Controller:

package br.com.kolss.boxml.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import br.com.kolss.boxml.dto.RetornoDTO;
import br.com.kolss.boxml.dto.UsuarioDTO;
import br.com.kolss.boxml.enums.RetornoEnum;
import br.com.kolss.boxml.service.UsuarioService;

@Controller
public class CadastroUsuariosController {

@Autowired
private UsuarioService usuarioService;

@RequestMapping(value="/usuario", method=RequestMethod.GET)
public ModelAndView iniciar(ModelMap modelMap){
    return new ModelAndView("usuario");
}

@RequestMapping(value="/usuario",method=RequestMethod.GET,produces={"application/json"})
public @ResponseBody List<UsuarioDTO> obterTodos(ModelMap modelMap){
    return usuarioService.obterTodos();
}

@RequestMapping(value = "/usuario/salvarUsuario", method = RequestMethod.POST, produces = { "application/json" })
public @ResponseBody RetornoDTO insereOuEditaUsuario(
        @RequestBody UsuarioDTO usuarioDTO) {

    usuarioService.insereOuEditaUsuario(usuarioDTO);
    return new RetornoDTO(RetornoEnum.SUCESSO);

}

}
halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

1

The date formatting to pt_BR only applies to how it is displayed in the datepicker control. Note that you are sending back a string mm/dd/yyyy to the server, you need to be sure that it is parsed as such at the controller.

  • Fran, first of all thanks for replying. That's exactly what I am trying to do, 'parse' the date to my controller. But this parse can be done, only by setting the format option that I did in my datepicker and it is not working... – Leonardo Leonardo Jan 07 '16 at 15:03
  • Can you post the piece of code in the `salvarUsuario` controller where you are accessing/reading the `dataValidadeConta` parameter? – Fran Rodriguez Jan 07 '16 at 15:21
  • I'm assuming that the UsuarioDTO model has a `dataValidadeConta` field of type Date. It fails when it tries to convert automatically the `mm/dd/yyyy` input into a Date object. From my point of view we have two options here: 1) In the javascript code, convert the date in a format which the default parser in the controller will be able to parse, or 2) In the model, define a custom parser to convert the `mm/dd/yyyy` into a Date. – Fran Rodriguez Jan 07 '16 at 16:35
  • Check these similar questions: http://stackoverflow.com/questions/25646564/unable-to-convert-string-to-date-by-requestbody-in-spring and http://stackoverflow.com/questions/21505997/passing-a-date-as-json-with-spring-mvc-and-jackson – Fran Rodriguez Jan 07 '16 at 16:36
  • Fran, about option 1), I did, it is in my javascript, but it is not parsing I do not know why. It has to work somehow, something is wrong but I did not catch. This is the correct way to parse, thought I do not know how to do it otherway. Thanks. – Leonardo Leonardo Jan 07 '16 at 16:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/100074/discussion-between-fran-rodriguez-and-leonardo-leonardo). – Fran Rodriguez Jan 07 '16 at 16:57