Problemas com conversão de tipos Date e String - O Spring ficou doido! [RESOLVIDO]

7 respostas
P

Bom Dia Senhores… estou fazendo uma pequena aplicação utilizando SpringMVC e o Oracle, nesta aplicação eu criei uma Classe Processo, onde nesta classe existem dois atributos, os quais são:

private Calendar dataAbertura;
private Calendar dataFechamento;

Ocorre que o Spring (me parece) não consegue converter em Date, esperando assim uma String para popular o objeto e persistir no Oracle… segue o Erro:

Grave: Servlet.service() for servlet [springMVC] in context with path [/projeto-am-sysJur-springMVC] threw exception [Request processing failed; nested exception is org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'processo' on field 'dataAbertura': rejected value [01/02/2013]; codes [typeMismatch.processo.dataAbertura,typeMismatch.dataAbertura,typeMismatch.java.util.Calendar,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [processo.dataAbertura,dataAbertura]; arguments []; default message [dataAbertura]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Calendar' for property 'dataAbertura'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property 'dataAbertura': no matching editors or conversion strategy found]] with root cause
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'processo' on field 'dataAbertura': rejected value [01/02/2013]; codes [typeMismatch.processo.dataAbertura,typeMismatch.dataAbertura,typeMismatch.java.util.Calendar,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [processo.dataAbertura,dataAbertura]; arguments []; default message [dataAbertura]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Calendar' for property 'dataAbertura'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property 'dataAbertura': no matching editors or conversion strategy found]
	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:810)

Fiz um teste mudando estes dois atributos, ou seja mudei de Calendar para String e onde estava assim:

private Calendar dataAbertura;
private Calendar dataFechamento;

ficou assim:

private String dataAbertura;
private String dataFechamento;

Mas confesso que, pra mim, é meio indigesto trabalhar com datas utilizando o tipo primitivo String! (rs) - Se alguém já passou por isso e puder ajudar… agradeço desde já!

Abraços e Feliz 2013!

7 Respostas

E

Creio que você precise criar algum tipo de conversor. Nunca usei SpringMVC mas creio que esse post resolva seu problema:

P

É eu tive vendo essa conversão em um outro site (http://www.roseindia.net/tutorial/spring/spring3/ioc/springvalidation.html), mas o que é mais engraçado é que eu acabei de terminar um projetinho com Spring e nele utilizei o Calendar sem problema algum… vai entender esses framewoks! rs mas valeu, o jeito é apelar para essa conversão mesmo!

R

O Spring MVC precisa de um conversor, até tem um nele, mas esse converte para java.util.Date, e no seu caso como precisa de um Calendar, vai precisar fazer o seu próprio.

P

Senhores está resolvido o problema agradeço a todos… o que estava faltando era a anotação do Spring no atributo da Classe, como segue abaixo:

@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataAbertura;
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataFechamento;

Essa anotação informa o framework que tal atributo trata-se de um Calendar ou Date…

Obrigado a todos… mas esse problema pelo menos aqui no GUJ, não tinha solução!

R

ppro11:
Senhores está resolvido o problema agradeço a todos… o que estava faltando era a anotação do Spring no atributo da Classe, como segue abaixo:

@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataAbertura;
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataFechamento;

Essa anotação informa o framework que tal atributo trata-se de um Calendar ou Date…

Obrigado a todos… mas esse problema pelo menos aqui no GUJ, não tinha solução!

Não conhecia essa anotação, pelo menos não como conversor, achei que ela funcionava apenas para uso do Validator.
Legal saber.

K

Pessoal, estou usando a mesma configuração para validar o formato da data, só não está 100%. Vejam como fiz:

Classe Empresa entity:

@Column(name="data_baixa")
@DateTimeFormat(pattern="dd/MM/yyyy")
//@Pattern(regexp = "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)")
//@Temporal(TemporalType.DATE)
private Date dataBaixa;

...

Meu controller metodo salvar:

@RequestMapping(value = "/cadastros/empresas", method = RequestMethod.POST)
	public String salvaEmpresa(@ModelAttribute("empresa") @Valid Empresa empresa, BindingResult result) {
				
		if (!result.hasErrors()){
			empresaDao.salvar(empresa);			
			return "redirect:/cadastros/empresas";
		} else {
			return "cadastros/empresas/create";
		}

	}

@InitBinder
protected void initBinder(WebDataBinder binder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true) );
    //binder.setValidator(validator);
}

Na view:

<form:input cssStyle="width:250px" maxlength="20" path="dataBaixa" size="10" cssClass="fieldGrid" id="dataInclusao" />

Só que o problema é como validar a data em si. Tipo: se eu colocar 40/13/2013 o sistema até salva, mas com uma data futura bem diferente.
Tentei usar um regexp para isso, conforme comentado, mas não tive sucesso:
Ocorre o erro: javax.validation.UnexpectedTypeException: No validator could be found for type: java.util.Date

Sou novo no spring, alguém sabe como posso validar a data em si com o framework?

Grato.

K

Buenas, pelo que vi, se utilizar junto o @temporal(TemporalType.DATE), uma validação é feita nos moldes que gostaria:

@Column(name="data_baixa")  
@DateTimeFormat(pattern="dd/MM/yyyy")  
//@Pattern(regexp = "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)")  
@Temporal(TemporalType.DATE)  
private Date dataBaixa;

Porém, por se tratar de uma validação do javax.persistence, ao informar uma data como 10/10/10001 ela não é tratada na propria tela como os alertas das anottations exe: org.hibernate.validator.constraint.NotEmpty que fiz utilizando messages.properties

Recebo um HTTP Status 500 - org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.DataException: Only dates between January 1, 1753 and December 31, 9999 are accepted.; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.DataException: Only dates between January 1, 1753 and December 31, 9999 are accepted.

Gostaria de tratá-la da mesma forma que a annotation notEmpty.

Criado 1 de janeiro de 2013
Ultima resposta 16 de abr. de 2013
Respostas 7
Participantes 4