Tempo de leitura: menos de 1 minuto
E aí Pessoal, tudo bem com vocês?
Estou muito feliz em anunciar que este é 101° post do blog. O blog foi criado em Dezembro de 2015, ainda é um bebê de 1 ano e 3 meses, mas já chegamos nesta marca expressiva. Agradeço a @debbyad pela ajuda, que publicou alguns destes posts e que continue a trazer ótimo conteúdos!
Mas vamos para o que interessa. Hoje vou falar sobre os Converters do Spring. Estas Classes são responsáveis por fazerem a conversão dos valores digitados no formulário para o atributo de um objeto.
Nos meus estudos/hands-on sobre Spring MVC, venho usando o framework Thymeleaf para resolver o V (Viewer) do MVC, e a cada dia estou gostando mais do poder deste framework.
Converters providos pelo Spring
Mas voltando aos converters, o Spring disponibiliza vários deles, desde para converter um simples numérico em String ou data no formato dd/MM/yyyy para um Date.
No entanto, no primeiro submit do formulário, me deparei com a exception abaixo. Isto me fez descobrir os converters e a necessidade de criar o meu próprio quando necessário.
Failed to convert property value of type java.lang.String to required type java.util.Calendar for property dtNascimento; nested exception is java.lang.IllegalStateException: Cannot convert value of type java.lang.String to required type java.util.Calendar for property dtNascimento: no matching editors or conversion strategy found
Esta exception é lançada quando o Spring não consegue converter uma String de um text field do formulário para o tipo do atributo no Model. Nesta caso, no formulário tinha um campo texto que representa uma data, e na entidade o atributo é do tipo Calendar, como o Spring não sabe converter String em um Calendar, eis o erro.
Mas como resolvermos este problema? Na verdade o Spring sabe converter String em Calendar, ele apenas precisa que configuremos o formato que a data virá do formulário.
Para isso, ele dispõem da anotação @DateTimeFormat. Esta anotação adicionada ao atributo Calendar na entidade, informa ao Spring que o atributo deverá ser convertido conforme o formato padrão que é M/d/yy.
https://gist.github.com/edermfl/077bf18767db3ffff794f170578006f8
Mais apenas isto não é suficiente já que a data no formulário está no formato dd/MM/yyyy. Caso você tente submiter o formulário novamente, usando o formato padrão, você receberá outra exception, algo parecida com isto:
Failed to convert property value of type java.lang.String to required type java.util.Calendar for property dtNascimento; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type @org.springframework.format.annotation.DateTimeFormat java.util.Calendar for value 2017-03-01; nested exception is java.lang.IllegalArgumentException: Unable to parse 2017-03-01
Neste caso é necessário informar o formato. Usei o atributo pattern para isto:
https://gist.github.com/edermfl/24c93d6ed3c623e7491344b937326bf1
Agora basta submeter o formulário novamente que o Spring fará o restante.
Converter personalizado
Nos meus testes, também me deparei com a necessidade de criar meu próprio converter. No formulário, tem um campo de múltipla escolha do tipo checkbox:
E na entidade eu espero receber uma lista de PapelAssociado:
https://gist.github.com/edermfl/7b67d9817e232a7703d3a6ac454acd66
O Spring não conhece está entidade PapelAssociado, com ele poderia fazer o bind do formulário para a entidade de forma transparente? Isto só foi possível criando meu próprio converter.
Para isto precisamos implementar a interface org.springframework.core.convert.converter.Converter. Abaixo segue minha implementação:
https://gist.github.com/edermfl/514b5b891c29d0904f672c2aaaa91e57
Simples não? O que faço aqui é receber a String pPapel (linha 3) e retornar um objeto do tipo PapelAssociado (linha 4). Para o Spring boot reconhecer esta classe como um converter, bastou anota-la como @Component.
Pronto, o Spring conseguirá agora fazer o bind do formulário para a entidade, sem maiores problemas.
Um dica que deixo é, caso você precise fazer o contrário, ou seja, da entidade fazer o bind para o formulário, você terá que criar outro converter, um que receba PapelAssociado e retorne String.
Se gostaram desta dica, dá uma curtida aí!!
Fonte: Spring MVC – Binding Java Backing Objects with Custom Converters
Caso você seja novato em Spring boot como eu e tenha interesse em aprender um pouco mais, sugiro a leitura dos posts anteriores sobre Spring Boot:
- Aprendendo Spring
- Aprendendo Spring: #1 – Startup de Projeto
- Aprendendo Spring: #2 – Configurando Beans
- Como tratar exceções e redirecionar erros usando Spring (Autoria de Débora Adorni)
- Aprendendo Spring: #3 – Enviando e-mail
Grande abraço.

Link permanente
Link permanente
Grato pelo artigo. Me ajudou bastante.
Link permanente
Que bom Wagner,
Fico feliz em ter ajudado!
Abraço!
Link permanente
Muito bom artigo. Clareou as minhas idéias!