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:
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:
... @RequestMapping("/pedidos") @Controller public class PedidoController { @RequestMapping(method = RequestMethod.POST) public String create(@Valid Pedido pedido, BindingResult bindingResult, Model uiModel) { if (bindingResult.hasErrors()) { //validador não aceitou o pedido, ele nao devera ser persistido ... } //o pedido foi validado com sucesso, pode ser persistido. ... } }
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:
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):
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
1 comment:
Este poste me deu uma grande ajuda! Parabéns!
Post a Comment