O Spring MVC provê funcionalidades para conversão e validação dos dados de formulários web, resolvendo a entrada de valores numéricos e datas, algo rotineiro em desenvolvimento de aplicações web. No
Spring MVC versão 3, além do suporte a anotações, algumas melhorias foram implementadas nesse setor.
Objetivo desse post é demonstrar como customizar/modificar as mensagens de erro geradas pelo Spring MVC durante a conversão de valores (
string) para data e/ou número.
De acordo com o trecho de código, a seguir, o bean Pedido é define alguns critérios para conversão e validação de dados:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import java.util.Date;
import java.math.BigDecimal;
public classe Pedido {
@NotNull
@DateTimeFormat (pattern = "dd/MM/yyyy" )
private Date dataAbertura;
@NotNull
@Digits (integer = 8 , fraction = 2 )
@NumberFormat (style=Style.NUMBER)
private BigDecimal valor;
...
}
|
As anotações
@NotNull e
@Digits são definidas em
Bean Validation (
JSR 303), o Spring as utiliza para validar o estado do objeto Pedido no lado servidor. As outras duas anotações são definidas pelo
Spring Framework:
- @DateTimeFormat: indica qual formato deve ser aplicado durante a conversão do conteúdo de um atributo data e/ou hora. A propriedade pattern, utilizada no exemplo acima, indica que a string informada pelo usuário deve respeitar dia/mês/ano. Outra opção é utilizar a propriedade style, que pré-define formatos para a data. Essa anotação pode demarcar atributos do tipo Date, Calendar, Long ou atributos do Joda Time.
- @NumberFormat: indica qual formato deve ser aplicado durante a conversão do conteúdo de um atributo numérico. A propriedade style, utilizada no exemplo acima, indica que a string informada pelo usuário deve respeitar um número decimal de acordo com as configurações do locale corrente. Outra alternativa seria utilizar propriedade pattern, e estipular o formato numérico suportado.
O próximo código demonstra um trecho da controller de pedidos, mais especificamente a assinatura do método que persiste (inclui) o objeto pedido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ...
@RequestMapping ( "/pedidos" ) @Controller
public class PedidoController {
@RequestMapping (method = RequestMethod.POST)
public String create( @Valid Pedido pedido,
BindingResult bindingResult, Model uiModel) {
if (bindingResult.hasErrors()) {
...
}
...
}
}
|
O argumento
pedido é um objeto preenchido com as informações inseridas pelo usuário, no formulário. Note que a variável foi demarcada com
@Valid (outra anotação de Bean Validation), dessa forma o Spring MVC valida essas informações, no lado servidor, de acordo com as definições da classe. Caso exista alguma(s) inconsistência(s), o Spring MVC preenche o objeto
bindingResult com o(s) erro(s). Por exemplo, se a
data do pedido não for preenchida o
if dentro do método deve cancelar o fluxo de inserção e retornar para o formulário.
Imagine que no formulário HTML o usuário preencheu um conteúdo incoerente para o campo
valor do pedido, por exemplo: '
abc'. Considerando que o formulário não realiza nenhuma validação/formatação no lado cliente (browser), como o Spring MVC se comportará ?
No momento de carregar o objeto o Spring MVC não consegue resolver
'abc' como um número decimal para o atributo (propriedade)
valor. O objeto
pedido é carregado com as informações que o Spring consegue converter. Antes de acionar o método na controller, o objeto bindingResult é notificado sobre o erro durante a conversão. Ao entrar no método
create, em
PedidoController, o atributo
valor do
pedido é
null, o mesmo trecho que valida o estado do pedido (
bindingResult.hasErrors()) é executado.
Dessa forma o formulário é recarregado, e o Spring MVC apresenta uma mensagem de erro contendo o seguinte texto:
"Failed to convert property value of type java.lang.String to required type java.math.BigDecimal"
Em outro cenário de conversão de dados, caso o usuário entre com o conteúdo inválido no campo da
data, o mesmo fluxo é executado, mas a mensagem apresentada será:
"Failed to convert property value of type java.lang.String to required type java.util.Date"
É possível customizar as mensagens com erro(s) de conversão do Spring?
Sim! No arquivo properties, com as mensagens internacionalizadas (
messages.properties) é possível modificar o conteúdo default as mensagens de conversão do Spring MVC.
É possível definir duas mensagens com erro de conversão de acordo com o tipo do atributo. O exemplo a seguir determina duas mensagens quer serão apresentadas para todos os atributos da aplicação, do tipo
java.util.Date e
java.math.BigDecimal. A seguir um exemplo de como isso pode ser feito:
1 2 | typeMismatch.java.util.Date=Conteúdo inválido para campo data!
typeMismatch.java.math.BigDecimal=Conteúdo inválido para campo numérico!
|
Outra opção é definir uma mensagem especifica para um determinado atributo. O exemplo a seguir determina um mensagem exclusiva para o atributo
valor do objeto
pedido (pedido deve ser o nome do argumento definido no método dentro da controller):
1 | typeMismatch.pedido.valor=O valor do pedido não foi preenchido corretamente!
|
Seguindo essa estratégia você utiliza o mecanismo de conversão e validação do Spring MVC, com uma mensagem mais amigável para o usuário.
Na
documentação do Spring é possível encontrar mais detalhes sobre o mecanismo de validação e conversão adotado pelo framework MVC.
@edermag
www.yaw.com.br