Vraptor 3.31 + Hibernate Validator - Messages Properties - Internacionalizar

37 respostas
R

Pessoal,

queria internacionalizar as mensagens do hibernate validator, para tal fiz assim no meu web.xml:

<context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
        <param-value>messages</param-value>
    </context-param>
    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.locale</param-name>
        <param-value>pt_BR</param-value>
    </context-param>

Coloquei meu arquivo messages.properties na pasta “classes” de WEB-INF

dominio.vazio = O nome do domínio não pode ficar em branco

No meu controller e no meu model, fiz isso:

@NotEmpty(message = "{dominio.vazio}")
     private String dominio;

  validator.validate(dominio);
        validator.onErrorUsePageOf(this).formulario();

e pra exibir a mensagem de erro:

<div id="erros">
        <ul>
            <c:forEach var="error" items="${errors}">
                <li>${error.message}</li>
            </c:forEach>
        </ul>
    </div>

Ele simplesmente exibe:

{dominio.vazio} ao invés de colocar a mensagem …

Alguém sabe porque??

A versão é a 4.0.2 que veio com o Vraptor!

37 Respostas

L

estranho, isso deveria funcionar… principalmente se vc estiver com a última versão do vraptor mesmo…

tenta dar um clean no projeto e no servidor e rodar de novo

R

Já tinha feito isso e nada!!

// validator.validate(dominio);
        validator.checking(new Validations() {

            {
                that(!dominio.getDominio().isEmpty(), "dominio", "dominio.vazio");
            }
        });

Coloquei assim e funcionou, mas quando vai pegar do hibernate validator, ele não internacionaliza…

Agora eu não sei qual é a versão do hibernate validator, tou colocando minhas libs em anexo … eu retirei todos os hibernate validator que eu tinha visto, mas ele tá “pegando” a referência de algum local ainda.

Quando vou no netbeans adicionar o “jar” do Hibernate Validator 3.04 ele disse que já tá no local, estranho … mas deve ser essa versão que estou usando, então! O erro persiste =/




L

qual é o import do @NotEmpty? do hibernate ou do javax.validations?

e se vc tirou o jar e ainda tá compilando, deve ter algum jar registrado a mais mesmo

R

Lucas,

Refiz todas as minhas referências, mas mesmo quando eu crio um novo projeto, sem lib alguma ele já pode importar isso:

import org.hibernate.validator.constraints.Length;

É daí que eu importo para usar a anotação, não sei de onde ele tá pegando isso, pois mesmo sem o jar do validator ele já acha …

Coloquei o jar do validator 4, e continuo sem receber a mensagem internacionalizada =/

Coloquei em anexo duas SS, de um projeto novo que eu criei e já consigo importar essa validação, sendo que ele só vêm com essas “libs”

esse hibernate.validator ele só está presente no jar hibernate validator? Tou até baixando a última versão do jdk, tentando de tudo =/

Valeu




R

Coloquei o jar do “validation-api”, continua com a mesma mensagem sem internacionalizar
=/

L

tenta importar de javax.validation

R

É para usar o javax validation ao invés do validation do hibernate?? Não consigo entender como ele continua importando as anotações do hibernate, mesmo sem a lib no projeto =/.

Vou fazer isso, então! O restante da lógica continua o mesmo. né?

Abs

L

sim

R

Lucas,

Substitui as anotações por @NotNull e @Size do javax.validation e mesmo assim, continuo recebendo a mesma mensagem {dominio.vazio} ao invés da mensagem internacionalizada.

Meu web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <session-config>
        <session-timeout>
            20
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <filter>
        <filter-name>vraptor</filter-name>
        <filter-class>br.com.caelum.vraptor.VRaptor</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>vraptor</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <jsp-config>
        <jsp-property-group>
            <description>SisTV</description>
            <display-name>SisTV</display-name>
            <url-pattern>*.jsp</url-pattern>
            <include-prelude>/header.jspf</include-prelude>
        </jsp-property-group>
    </jsp-config>

    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
        <param-value>messages</param-value>
    </context-param>
    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.locale</param-name>
        <param-value>pt_BR</param-value>
    </context-param>
  <context-param>

        <param-name>br.com.caelum.vraptor.encoding</param-name>

        <param-value>UTF-8</param-value>

    </context-param>
</web-app>

Tou usando o GlassFish 3.1 e na lib que vem com ele, tem o

“Bean-validator.jar” que tem o hibernate.validator e o javax.validator , por isso eu fiquei confuso quando tirei as referências dos hibernate validator e ele continuava achando …

Valeu pela ajuda, tou aqui na luta pra resolver isso!

L

tenta criar um arquivo chamado ValidationMessages.properties, no mesmo diretório que o messages.properties, e coloca a internacionalização lah

R

Lucas,

Funcionou o “ValidationMessage.properties” , alguma convenção do vraptor não funcionou para o messages? O que aconteceu, ao certo?

Desculpa perguntar essas coisas, é que eu não consigo simplesmente receber a solução, sem entendê-la ehhe!

L

acho que é um bug mesmo…
https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/validator/JSR303Validator.java

ele não usa o bundle do VRaptor… marca uma issue por favor?

R

Ok, vou fazer

R

Pronto:

L

valeu! =)

vou tentar corrigir isso antes do próximo release (ou se vc estiver a fim de corrigir e mandar um pull request, vou gostar bastante tb =))

R

Lucas,

Aproveitando o tópico…

Tem como internacionalizar a mensagem do Caelum validator cpf??

coloquei a tag @Cpf(message = {cpf.invalido} ele internacionaliza isso?

L

teoricamente sim

R

Lucas,

import br.com.caelum.stella.hibernate.validator.CPF;
    

@CPF(message = "{cpf.invalido}")
     @NotEmpty(message="{cpf.vazio}")
     private String cpf;

 //Controller
   validator.validate(solicitante);
        validator.onErrorUsePageOf(this).formulario();

O Vraptor ao chamar o método validate, nem usa o stella validator cpf . Passei um CPF inválido e ele não apontou erros, acredito que não dê pra usar com o método validate.

L

você está com os jars do hibernate validator 3 ou 4?

se estiver com o 4, use a nova versão do Stella, que foi lançada ontem:
http://repo1.maven.org/maven2/br/com/caelum/stella/caelum-stella-bean-validation/2.0-beta1/caelum-stella-bean-validation-2.0-beta1.jar

e nos dê o feedback se está funcionando, por favor

G

Isso não é um bug do VRaptor não. O padrão do Bean Validator e Hibernate Validator é usar o ValidationMessages.properties.

R

Creio que a versão seja 4.1, ele tá no “BeanValidator” que vêm junto com a lib do glassfish 3.1, vou testar a nova versão do stella … A propósito, o site estava fora né?

R

Coloquei o Jar do novo Caelum validator:

import br.com.caelum.stella.bean.validation.CPF;


  @CPF
     @NotEmpty(message="{cpf.vazio}")
     private String cpf;

//Controller


    @Post
    @Path("/solicitantes/novo")
    public void adiciona(Solicitante solicitante) {
        validator.validate(solicitante);
        validator.onErrorUsePageOf(this).formulario();

Passei essa string como cpf: [CPF removido]

Depurando eu vi que ele não aponta nenhum erro pro CPF e continua a lógica normal, mesmo passando um cpf inválido

A versão do hibernate validator é a 4.1 que veio com a lib “Bean Validator”

** Tirei a validação do “NotEmpty” e também não funcionou =/

M

oi rafaelob, tudo bem?

Nesse caso que você mostrou, o @NotEmpty funcionou ou nenhum dos dois?

[]'s

R

Olá,

O “NotEmpty” funcionou sim, só comentei que eu retirei ele e deixei só a anotação do Caelum.Stella.Bean.Validator , que não funcionou. As anotações do Hibernate Validator 4.1 , estão funcionando com o método validate(object). Só não consigo que a validação do Caellum Stella funcione, ele simplesmente ignora essa validação.

M

Oi Rafael

Eu realizei alguns testes aqui e funcionou normal, talvez seja alguma diferença de ambiente que não estamos percebendo.

Criei um projeto no github com o código do teste que realizamos aqui, você pode baixar e rodar pra comparar com o seu ambiente, o link é https://github.com/mariofts/test-vraptor-stella

[]'s

R

Mario,

Mudei do beta1 para o beta2 e funcionou perfeitamente.

Obrigado…

Att,

G

Comentei já isso lá no Github, mas vou deixar aqui para quem precise. Isso não é um problema do VRaptor porque ele apenas delega ao Bean Validator. O padrão do Bean Validator é que o arquivo esteja no classpath com o nome ValidationMessages.properties e suas variantes. Qualquer implementação do Bean Validator vai procurar nesses locais, e isso não há como mudar.

A meu ver não é legal misturar um arquivo de mensagens da aplicação com o arquivo de mensagens de validação. Mesmo que desse para colocar tudo em um só, não é muito elegante não.

Maaaas… se mesmo assim você quiser, dá para fazer uma gambiarra muuuito feia. Detalhe que isso só funciona se você usar o Hibernate Validator 4 como implementação para Bean Validator, perdendo a portabilidade.

Você deve sobrescrever o componente MessageInterpolatorFactory no método createInterpolator:

@PostConstruct public void createInterpolator() { interpolator = new MyBizarreInterpolator(); logger.debug("Initializing JSR303 MessageInterpolator"); }

Depois crie a classe MyBizarreInterpolator usando a classe ResourceBundleMessageInterpolator como exemplo alterando o local do resource bundle a teu critério.


http://grepcode.com/file/repository.jboss.org/maven2/org.hibernate/hibernate-validator/4.0.0.CR1/org/hibernate/validator/engine/ResourceBundleMessageInterpolator.java/?v=source

R

Aproveitando o tópico, tem alguma maneira de eu internacionalizar uma mensagem do método:

validator.add(new ValidationMessage("{dominio.negado}","{dominio.negado}" )); ou só usando aquela maneira fluente mesmo??

Grato =)

L

na última versão é só usar new I18nMessage(“categoria”, “dominio.negado”, parametros); ao invés de ValidationMessage

R

Valeu, Lucas!

R

Aproveitando o tópico…

O VRaptor não internacionaliza os parametros de forma automatica das anotações impostas pela JSR303 @Size, @Min, @Max ?

Por exemplo, poderia ter a mensagem:
javax.validation.constraints.Min.message=o valor informado dever ser maior ou igual a {0}.

L

não é o VRaptor que faz isso, é o Bean Validations…

o certo não é usar {0}, é usar o nome da propriedade da anotação. Por padrão é value:

@Min(3) ==> ....maior ou igual a {value}
@Max(5) ==> ...menor ou igual a {value}
@Range(min=3, max=5) ==> ...entre {min} e {max}
R

Lucas Cavalcanti:
não é o VRaptor que faz isso, é o Bean Validations…

o certo não é usar {0}, é usar o nome da propriedade da anotação. Por padrão é value:

@Min(3) ==> ....maior ou igual a {value} @Max(5) ==> ...menor ou igual a {value} @Range(min=3, max=5) ==> ...entre {min} e {max}


Certo, entendi como deve ser usado.

Gostaria de levantar uma outra duvida, na empresa que trabalho eles mantem em um sistema pararelo todo o DER usado por seus sistemas. Assim é o próprio analista que informa qual será o label aplicado a cada campo e qual é nome de dominio da tabela e colunas.
Para facilitar a vida dos desenvolvedores, esse sistema exporta esses labels do banco seguindo esse padrao:

O detalhe que esse padrão não é o adotado pelo VRaptor para criar as mensagens de inconsistencias encontrados pelo Bean Validations. Que utiliza apenas o nome do atributo que apresentou algum problema.
Quero saber se há possibilidade através do componente do VRaptor customizar essa resolução da “categoria” da mensagem ou terei que implementar um outro componente de validacao usando a JSR303 e saiba o nome a setar ?

Lucas, novamente um obrigado pelo esclarecimento.

L

dá pra customizar sim…

crie essa classe:

@Component
public class CustomValidator extends DefaultValidator {
    //delegate constructor
    public CustomValidator(......, TypeNameExtractor extractor) {
         super(...);
         this.extractor = extractor;
    }
    
    @Override
    public void validate(Object object) {
            String prefix = extractor.nameFor(object.getClass()) + ".";
            for (BeanValidator validator : beanValidators) {
                List<Message> messages = validator.validate(object);
                for(Message message : messages) {
                    add(new ValidationMessage(message.getMessage(), prefix + message.getCategory());
                }
            }
    }

}
T

Aproveitando o tópico, gostaria de saber se tem como enviar um parametro para a mensagem em ValidationMessages.properties, usando o hibernate validator, tipo assim:

@NotEmpty(message="{nao.vazio}")

@Length(min=3, message="{maior.que}")

private String nome;

e o arquivo ValidationMessages.properties está assim:

nao.vazio={0} não pode ser vazio.
maior.que={0} deve ser possuir mais que {min} caractereres

, Onde {0} eu quero que seja o nome da propriedade (nesse caso “nome”)

E aí, tem como?

L

não. Pelo menos não sem hackear bastante o BeanValidations;

use o error.category pra isso.

T

Hum, beleza. Valeu Lucas!

Criado 26 de maio de 2011
Ultima resposta 21 de jun. de 2012
Respostas 37
Participantes 6