Mudanças entre as edições de "RFWBundle"

De Wiki do Leitão
Ir para: navegação, pesquisa
Linha 26: Linha 26:
==== '''get(Throwable t)''' ====
==== '''get(Throwable t)''' ====
O método '''get''' sobrecarregado com um parâmetro do tipo `Throwable` é usado para recuperar e formatar mensagens baseadas em exceções, especialmente aquelas que herdam de '''[[RFWException]]'''. Ele percorre a cadeia de causas da exceção para identificar a raiz do problema e formata a mensagem correspondente, incluindo detalhes como a classe da exceção e os parâmetros associados.
O método '''get''' sobrecarregado com um parâmetro do tipo `Throwable` é usado para recuperar e formatar mensagens baseadas em exceções, especialmente aquelas que herdam de '''[[RFWException]]'''. Ele percorre a cadeia de causas da exceção para identificar a raiz do problema e formata a mensagem correspondente, incluindo detalhes como a classe da exceção e os parâmetros associados.


{{nota|Tratamento Específico para RFWValidationException|
{{nota|Tratamento Específico para RFWValidationException|
Se a exceção recebida for uma instância de `RFWValidationException`, o método realiza substituições adicionais na mensagem além dos parâmetros padrão `${0}`, `${1}`, etc. As variáveis suportadas incluem:
Se a exceção recebida for uma instância de '''[[RFWValidationException]]''', o método realiza substituições adicionais na mensagem além dos parâmetros padrão `${0}`, `${1}`, etc. As variáveis suportadas incluem:


* `'''${fieldname}'''`: Substituído pelos nomes dos campos da classe que causaram a validação a falhar.
* '''${fieldname}''': Substituído pelos nomes dos campos da classe que causaram a validação a falhar.
* `'''${classname}'''`: Substituído pelo nome da classe onde ocorreu a falha de validação.
* '''${classname}''': Substituído pelo nome da classe onde ocorreu a falha de validação.
* `'''${cause}'''`: Substituído pelo nome da classe da causa original da exceção.
* '''${cause}''': Substituído pelo nome da classe da causa original da exceção.


Essas substituições permitem que a mensagem seja mais informativa e específica ao contexto da validação que falhou.
Essas substituições permitem que a mensagem seja mais informativa e específica ao contexto da validação que falhou.
Linha 38: Linha 39:
}}
}}


É um método criado para tentar obter o bundle diretamente dos erros (Throwables). Esta método considera que está em uso o padrão de [[Exceções & Tratamento]] do RFW.
O método funciona na seguinte cascata para obter o bundle:
* O Throwable é instância de RFWException?
** '''Sim:''' Tem um 'ExceptionCode' definido no padrão "'''[A-Z0-9_]+'''"?
*** '''Sim:''' Busca a mensagem de Bundle pelo 'ExceptionCode' e tenta substituir os parâmetros na mensagem.
** '''Não:''' Retornará '''CanonicalName''' + '''Message (se Existir)''' + " at " + '''StackTrace()[0]'''
{{nota|Parâmetros das Exceptions|Note que os parâmetros que são substituídos no bundle são os mesmos passados na RFWException, seguindo a mesma lógica do método get(String, String...).}}


==== '''get(Enum<?> value)''' ====
==== '''get(Enum<?> value)''' ====

Edição das 14h46min de 4 de setembro de 2024

RFWBundle

Introdução

Visão Geral

O RFWBundle é uma classe estática que centraliza a gestão de mensagens no sistema, permitindo a recuperação de mensagens configuráveis a partir de arquivos de propriedades, conhecidos como bundles. Essas mensagens são amplamente utilizadas para fornecer feedback ao usuário, registrar logs, e suportar a internacionalização da aplicação. O RFWBundle facilita a substituição de parâmetros dinâmicos nas mensagens, tornando-as adaptáveis a diferentes contextos e necessidades.

Contexto de Uso

O RFWBundle é utilizado em diversos pontos do sistema onde é necessário recuperar mensagens de forma consistente e centralizada. Situações típicas de uso incluem:

  • Internacionalização: Suporte a múltiplos idiomas através da recuperação de mensagens configuradas em arquivos de propriedades específicos para cada idioma.
  • Gestão de Erros e Logs: Recuperação de mensagens de erro e avisos a partir de chaves definidas, com a capacidade de personalizar a mensagem com parâmetros específicos.
  • Flexibilidade de Configuração: Permite que as mensagens do sistema sejam alteradas sem modificar o código-fonte, bastando atualizar os arquivos de bundle, o que facilita a manutenção e a adaptação do sistema a diferentes ambientes e requisitos.

A classe RFWBundle é essencial para sistemas que necessitam de uma camada de apresentação de mensagens flexível e facilmente configurável, garantindo que as informações exibidas ou registradas sejam coerentes e adaptadas ao contexto de uso.

Estrutura e Componentes

Métodos Principais

loadBundle

O método loadBundle é responsável por carregar os arquivos de propriedades (bundles) que contêm as mensagens utilizadas pelo sistema. Ele deve ser chamado com um nome de arquivo específico. Se o bundle já estiver carregado uma exceção crítica (`RFWCriticalException`) será lançada. Este método garante que as mensagens estejam disponíveis para recuperação por outros métodos da classe.

get(String key, String... params)

O método get é utilizado para recuperar uma mensagem associada a uma chave específica do bundle. Além disso, ele permite a substituição de parâmetros dinâmicos dentro da mensagem, utilizando placeholders como `${0}`, `${1}`, etc. Isso torna as mensagens adaptáveis a diferentes contextos ao inserir informações específicas em tempo de execução.

get(Throwable t)

O método get sobrecarregado com um parâmetro do tipo `Throwable` é usado para recuperar e formatar mensagens baseadas em exceções, especialmente aquelas que herdam de RFWException. Ele percorre a cadeia de causas da exceção para identificar a raiz do problema e formata a mensagem correspondente, incluindo detalhes como a classe da exceção e os parâmetros associados.


Note 64.png
Tratamento Específico para RFWValidationException

Se a exceção recebida for uma instância de RFWValidationException, o método realiza substituições adicionais na mensagem além dos parâmetros padrão `${0}`, `${1}`, etc. As variáveis suportadas incluem:

  • ${fieldname}: Substituído pelos nomes dos campos da classe que causaram a validação a falhar.
  • ${classname}: Substituído pelo nome da classe onde ocorreu a falha de validação.
  • ${cause}: Substituído pelo nome da classe da causa original da exceção.

Essas substituições permitem que a mensagem seja mais informativa e específica ao contexto da validação que falhou. Os valores dessas variáveis podem ser definidos nos construtores da RFWValidationException.


É um método criado para tentar obter o bundle diretamente dos erros (Throwables). Esta método considera que está em uso o padrão de Exceções & Tratamento do RFW.

O método funciona na seguinte cascata para obter o bundle:

  • O Throwable é instância de RFWException?
    • Sim: Tem um 'ExceptionCode' definido no padrão "[A-Z0-9_]+"?
      • Sim: Busca a mensagem de Bundle pelo 'ExceptionCode' e tenta substituir os parâmetros na mensagem.
    • Não: Retornará CanonicalName + Message (se Existir) + " at " + StackTrace()[0]


Note 64.png
Parâmetros das Exceptions
Note que os parâmetros que são substituídos no bundle são os mesmos passados na RFWException, seguindo a mesma lógica do método get(String, String...).

get(Enum<?> value)

O método get com um parâmetro `Enum` é projetado para recuperar mensagens associadas a valores de enumerações. Ele constrói a chave do bundle a partir do valor da enumeração e tenta recuperar a mensagem correspondente. Se a chave não for encontrada no bundle, um aviso é registrado usando o RFWLogger.

get(MeasureUnit measureUnit)

O método get com um parâmetro MeasureUnit lida com a recuperação de mensagens associadas a unidades de medida. Ele trata instâncias de CustomMeasureUnit de maneira especial, formatando a mensagem com o símbolo e o nome da unidade. Para outras unidades de medida, ele delega a recuperação ao método que lida com enums.

replaceParameters

O método replaceParameters é responsável por substituir placeholders na mensagem recuperada pelo bundle com os valores fornecidos em um array de strings. Placeholders têm o formato `${0}`, `${1}`, e assim por diante, onde o número representa o índice do array de parâmetros.

  • Funcionamento:
    • O método percorre a mensagem original, identificando os placeholders e substituindo-os pelos valores correspondentes do array.
    • Se um parâmetro for nulo, ele é substituído pela string `"<null>"` para evitar que o placeholder permaneça inalterado na mensagem final.
  • Uso Interno:
    • Esse método é utilizado internamente pelos métodos `get(String key, String... params)` e `get(Throwable t)` para personalizar as mensagens retornadas, garantindo que elas contenham informações específicas do contexto de uso.
  • Exemplo de Substituição:
    • Dada uma mensagem original `"Erro ao processar a transação ${0} na conta ${1}"` e os parâmetros `{"12345", "67890"}`, o método retornaria `"Erro ao processar a transação 12345 na conta 67890"`.

Carregamento e Configuração do Bundle

Processo de Carregamento

O carregamento do bundle é uma etapa crucial para o funcionamento do RFWBundle. Isso é realizado pelo método loadBundle, que carrega os arquivos de propriedades (bundles) que contêm as mensagens utilizadas em todo o sistema.

  • Funcionamento:
    • O método tenta carregar o bundle especificado pelo nome do arquivo passado como parâmetro.
    • O bundle é carregado na primeira vez que o método é chamado e armazenado no atributo estático `bundle`. Isso garante que o arquivo de propriedades esteja disponível para futuras chamadas de recuperação de mensagens sem a necessidade de recarregá-lo.
  • Recarregamento:
    • Se o bundle já estiver carregado e um novo nome de arquivo for passado para o método, ele tenta carregar o novo bundle e mesclar as propriedades, preservando as já existentes.
    • No entanto, se o bundle já estiver carregado e o nome do arquivo não for especificado, uma exceção crítica (RFWCriticalException) será lançada para evitar a inconsistência no carregamento das propriedades.

Bundles Padrão

Por padrão, o RFWBundle carrega seus arquivos de propriedades básicos, que contém os bundles do próprio módulo RFW.

Esses bundles são automaticamente carregados na primeira chamada do método loadBundle, garantindo que as mensagens essenciais do sistema estejam disponíveis desde o início. Se sua aplicação requer bundles adicionais, você pode chamar o método com o nome do arquivo necessário logo após a inicialização.

Erro ao Carregar Bundles

O método loadBundle lida com possíveis erros durante o carregamento do arquivo de propriedades, como falhas ao localizar o arquivo ou problemas de I/O.

  • Tratamento de Exceções:
    • Se ocorrer uma exceção de I/O durante o carregamento, o método lançará uma RFWCriticalException com uma mensagem apropriada e a chave do bundle que causou o erro.
    • Esse tratamento garante que qualquer falha no carregamento do bundle seja imediatamente identificada e registrada, permitindo ações corretivas rápidas e evitando comportamentos inesperados no sistema.

O processo de carregamento e configuração do bundle é projetado para ser robusto e flexível, garantindo que as mensagens estejam disponíveis e prontas para uso logo no início da execução do sistema.

Recuperação de Mensagens

Chaves e Substituição de Parâmetros

A recuperação de mensagens no RFWBundle é realizada principalmente pelo método get(String key, String... params). Esse método permite recuperar uma mensagem associada a uma chave específica no bundle e, se necessário, substituir parâmetros dinâmicos na mensagem.

  • Funcionamento:
    • O método aceita uma chave como argumento, que é usada para localizar a mensagem correspondente no bundle.
    • Parâmetros adicionais podem ser passados como strings, que substituem os placeholders na mensagem recuperada. Esses placeholders têm o formato `${0}`, `${1}`, etc., onde o número corresponde à posição do parâmetro no array.
  • Exemplo de Uso:
    • Considere que o bundle contém a seguinte entrada: `ERRO_TRANSACAO=Erro ao processar a transação ${0} na conta ${1}`. Ao chamar `get("ERRO_TRANSACAO", "12345", "67890")`, o método retornará a mensagem `"Erro ao processar a transação 12345 na conta 67890"`.

Esse método é amplamente utilizado em todo o sistema para garantir que as mensagens sejam claras e adaptadas ao contexto específico, substituindo dinamicamente os valores necessários.

Mensagens Baseadas em Exceções

Além da recuperação de mensagens com base em chaves, o RFWBundle também oferece suporte para a recuperação de mensagens diretamente associadas a exceções, através do método get(Throwable t).

  • Funcionamento:
    • O método percorre a cadeia de causas da exceção recebida, identificando a raiz do problema. Se a exceção for uma instância de `RFWException`, o método tentará recuperar a mensagem correspondente ao código de exceção.
    • Parâmetros específicos da exceção, como detalhes da classe onde ocorreu o erro e a mensagem da exceção, são substituídos na mensagem recuperada.
  • Tratamento Específico para RFWValidationException:
    • Se a exceção for uma `RFWValidationException`, o método também substitui placeholders adicionais, como `${fieldname}`, que representa os nomes dos campos que falharam na validação, e `${classname}`, que substitui o nome da classe onde a validação falhou.
  • Exemplo de Uso:
    • Se uma exceção `RFWValidationException` for lançada devido a um erro de validação no campo "username" da classe "User", e o bundle contiver a entrada `VALIDATION_ERROR=Erro de validação nos campos: ${fieldname} da classe ${classname}`, o método `get(Throwable t)` retornará a mensagem `"Erro de validação nos campos: username da classe User"`.

Tratamento de Enums

O método get(Enum<?> value) é utilizado para recuperar mensagens associadas a valores de enumerações. Esse método constrói a chave do bundle com base no CanonicalName da enumeração e tenta recuperar a mensagem correspondente.

  • Funcionamento:
    • O método gera uma chave usando o CanonicalName da enumeração e tenta encontrar uma mensagem correspondente no bundle.
    • Se a chave não for encontrada, o método retorna o nome completo da enumeração como fallback e registra um aviso no log utilizando o RFWLogger.
  • Exemplo de Uso:
    • Para uma enumeração `Status`, declarada em uma classe cujo CanonicalName seja 'com.example.Document' com valores como `PENDING`, o método `get(Status.PENDING)` tentará recuperar a mensagem correspondente à chave `com.example.Document.Status.PENDING`. Se não encontrar a chave ela será retornada como valor.

Unidades de Medida

O método get(MeasureUnit measureUnit) lida com a recuperação de mensagens associadas a unidades de medida do componente [MeasureUnit]], incluindo o suporte para instâncias de `CustomMeasureUnit`.

  • Funcionamento:
    • Se o parâmetro passado for uma instância de `CustomMeasureUnit`, o método formatará a mensagem usando o símbolo e o nome da unidade. Caso contrário, ele delegará a recuperação ao método de enumerações, já que `MeasureUnit` geralmente funciona como uma enumeração.

Exemplos Práticos

Inicialização do Bundle

Para carregar um arquivo de bundle específico, como "bundledoseuapp.properties", você pode inicializar o bundle usando o método loadBundle. O arquivo de bundle deve estar localizado na raiz de qualquer pacote acessível pelo classloader ou o caminho completo a partir da raiz do pacote deve ser passado.

Note 64.png
Localização do Arquivo de Bundle
O arquivo de bundle deve estar na raiz de um pacote acessível pelo classloader ou seu caminho completo deve ser informado a partir da raiz do pacote.

Exemplo de inicialização do bundle:

RFWBundle.loadBundle("bundledoseuapp.properties");

Este comando carrega o bundle específico, tornando suas mensagens acessíveis para o restante da aplicação.

Note 64.png
Carregamento do Bundle por ClassLoader

Uma vez carregada na classe estática RFWBundle o bundle é acessivel de qualquer lugar do ClassLoader. Se for uma aplicação simples, você pode carregar seu bundle já no início, por exemplo no método main().

Se estiver com uma aplicação J2EE, e dependendo do servidor de aplicação, pode ser necessário carregar o Bundle em lugares diferentes. Por exemplo, o WildFly utiliza um ClassLoader para o WAR e outros para os EJB, mesmo que compartilhem as classes disponíveis na pasta lib/ do EAR. Assim é necessário que o Bundle seja carregado uma vez em cada ClassLoader. A recomendação é que no WAR seja criado um Servlet que seja inicializado já no deploy, e que faça o carregamento dos Bundles nesse ClassLoader. Assim como nos módulos EJB, podem ser criados métodos de @PostConstruct que já se iniciam durante o deploy e fazem o carregamento do Bundle.


Exemplo 1: Recuperação Simples de Mensagem

Neste exemplo, vamos recuperar uma mensagem simples de um bundle utilizando o método get(String key, String... params). Suponha que o bundle contém a seguinte mensagem:

ERRO_TRANSACAO=Erro ao processar a transação ${0} na conta ${1}.

Agora, no código:

String mensagem = RFWBundle.get("ERRO_TRANSACAO", "12345", "67890");
System.out.println(mensagem);

Saída:

Erro ao processar a transação 12345 na conta 67890.

O método substitui os placeholders `${0}` e `${1}` pelos valores passados como parâmetros, retornando a mensagem completa e formatada.

Exemplo 2: Tratamento de Exceções com Mensagens

Neste exemplo, usaremos o método get(Throwable t) para lidar com uma exceção e gerar uma mensagem adequada. Suponha que você tenha uma exceção personalizada RFWValidationException lançada devido a uma falha de validação.

try {
    // código que lança uma RFWValidationException
} catch (RFWValidationException e) {
    String mensagem = RFWBundle.get(e);
    System.out.println(mensagem); 
}

Se o bundle contiver a seguinte mensagem para erros de validação:

VALIDATION_ERROR=Erro de validação nos campos: ${fieldname} da classe ${classname}.

E a exceção contiver as informações de que o campo "username" da classe "User" falhou na validação, a saída será:

Erro de validação nos campos: username da classe User.

Esse exemplo mostra como o RFWBundle recupera e substitui dinamicamente os parâmetros da exceção para criar uma mensagem descritiva e útil.

Exemplo 3: Uso de Enums no Bundle

Aqui, usaremos o método get(Enum<?> value) para recuperar uma mensagem associada a uma enumeração. Suponha que temos a seguinte enumeração Status:

public enum Status {
    PENDING,
    APPROVED,
    REJECTED
}

E o bundle contém a seguinte mensagem:

Status.PENDING=Transação pendente de aprovação.

Agora, ao chamar:

String mensagem = RFWBundle.get(Status.PENDING);
System.out.println(mensagem);

Saída:

Transação pendente de aprovação.


Se a chave correspondente à enumeração não for encontrada no bundle, o método retornará o nome completo da enumeração, e um aviso será registrado no log.

Exemplo 4: Trabalhando com Unidades de Medida

Neste exemplo, usaremos o método get(MeasureUnit measureUnit) para lidar com uma unidade de medida personalizada. Suponha que temos uma classe CustomMeasureUnit que implementa a interface MeasureUnit e representa "caixa":

CustomMeasureUnit kg = new CustomMeasureUnit("cx", "Caixa");
String mensagem = RFWBundle.get(kg);
System.out.println(mensagem);

A saída será formatada como:

cx (Caixa)


O método trata as unidades personalizadas e formata corretamente a representação da unidade de medida, retornando o símbolo e o nome completos.

Considerações Finais

Resumo dos Benefícios

O RFWBundle oferece uma abordagem centralizada e eficiente para gerenciar mensagens configuráveis no sistema. Ele permite a recuperação de mensagens baseadas em chaves de bundle, com suporte para a substituição dinâmica de parâmetros. Seus principais benefícios incluem:

  • Centralização de Mensagens: Todas as mensagens do sistema são gerenciadas em arquivos de propriedades centralizados, facilitando a manutenção e a atualização sem necessidade de alterações no código.
  • Suporte à Internacionalização: O RFWBundle oferece uma solução fácil para a internacionalização de mensagens, possibilitando a troca de mensagens de acordo com o idioma sem impactar a lógica do sistema (à Implementar).
  • Tratamento de Exceções e Parametrização: Com o suporte para substituição de parâmetros e formatação de mensagens de exceções, ele proporciona maior clareza e precisão nas mensagens de erro e validação.
  • Flexibilidade para Customizações: A capacidade de trabalhar com enums, unidades de medida personalizadas e exceções permite que o sistema seja altamente adaptável a diferentes cenários.

Possíveis Melhorias e Expansões

Embora o RFWBundle já forneça uma base robusta para o gerenciamento de mensagens, há algumas áreas que podem ser exploradas para futuras melhorias:

  • Implementação Real da Intenacionalização: Atualmente, o RFWBundle só é capaz de centralizar as mensagens do sistema, ainda é necessário realizar a implementação para receber um Locale e obter a mensagem do bundle localizado ao invés de apenas do bundle padrão.
  • Suporte para Múltiplos Formatos de Bundle: Expandir o suporte para formatos adicionais de arquivo de bundle, como JSON ou YAML, pode oferecer mais flexibilidade em ambientes modernos de desenvolvimento.
  • Integração com Sistemas de Tradução: Uma melhoria possível seria integrar o RFWBundle com serviços externos de tradução automática, facilitando a manutenção de mensagens internacionalizadas em tempo real.
  • Melhorias na Performance: Implementar caching inteligente para reduzir o impacto do carregamento de grandes bundles, especialmente em sistemas com alta demanda de I/O.

Com essas considerações em mente, o RFWBundle pode continuar evoluindo para atender às necessidades crescentes de sistemas complexos, garantindo uma gestão eficiente de mensagens e suporte contínuo à internacionalização e personalização.

Conteúdo Anterior

O RFWBundle é um serviço de Bundle oferecido pelo RFW. A classe estática RFWBundle ao ser inicializada já carrega os bundles do próprio RFW, trazendo as mensagens para as exceptions e Enumarations do próprio framework.

Carregando Arquivos de Bundles

Para incluir um arquivo de properties dentro do RFWBundle, deve ser chamado o método loadBundle(...) e passar o novo arquivo de bundle. Também é possível realizar a operação ao inicializar o framework, pelo método initializeBundle(...) da classe RFW.

Java 256.png Carregando Arquivo de Bundle
RFWBundle.loadBundle("bundlefile.properties");


Obtendo o Bundle

Para obter o Bundle o RFWBundle oferece os métodos get(...). Dependendo do objeto passado o módulo é capaz de extrair a chave e procurar nos arquivos de bundle automaticamente. Veja os detalhes de cada método a seguir:

get(Enum<?>)

Este método recebe como um argumento um objeto de Enumeração. O objeto de enumeração é procurado no arquivo de bundle pelo CanonicalName da sua Classe + Name da Enmeration. Por exemplo, imagine a Enumeration CASE_INSENSITIVE_ORDER da classe java.lang.String, será convertida na chave java.lang.String.CASE_INSENSITIVE_ORDER, para procurar entre os arquivos de bundle.

Neste caso, o arquivo de bundle deve ter uma entrada similar a esta:

java.lang.String.CASE_INSENSITIVE_ORDER=Ordem sem sensibilidade de caixa alta.


Note 64.png
RUString.getEnumKey()
A classe [RUString] contém um método getEnumKey(Enum<?>) que retorna exatamente a chave do Enumeration passado, mesmo método utilizado pelo RFWVBundle.


get(String, String...)

Recupera os bundles dos arquivos e substitui propriedades dentro deles. Este método procura por bundles que tenham o texto ${i}, onde i é o índice do array recebido para substituir seu conteúdo.

Por exemplo, o bundle seja:

warnmsg=Mensagem de erro (${0}): ${1}


E código executado seja:

Java 256.png Obtendo o conteúdo do Bundle
String v = RFWBundle.get("warnmsg", "500", "Erro Crítico");

O conteúdo da variável v será "Mensagem de Erro (500): Erro Crítico".

get(MeasureUnit)

Similar o método de Enumeration, ele recebe um objeto da interface MeasureUnit e se resolve para tentar descobrir o enumeration correto. Para mais informações sobre esta classe veja mais sobre o MeasureRuler.

get(Throwable)

É um método criado para tentar obter o bundle diretamente dos erros (Throwables). Esta método considera que está em uso o padrão de Exceções & Tratamento do RFW.

O método funciona na seguinte cascata para obter o bundle:

  • O Throwable é instância de RFWException?
    • Sim: Tem um 'ExceptionCode' definido no padrão "[A-Z0-9_]+"?
      • Sim: Busca a mensagem de Bundle pelo 'ExceptionCode' e tenta substituir os parâmetros na mensagem.
    • Não: Retornará CanonicalName + Message (se Existir) + " at " + StackTrace()[0]


Note 64.png
Parâmetros das Exceptions
Note que os parâmetros que são substituídos no bundle são os mesmos passados na RFWException, seguindo a mesma lógica do método get(String, String...).


No caso de ser a exception de validação RFWValidationException, o RFW ainda tem algumas variáveis adicionais que podem ser utilizadas no bundle:

  • ${fieldname} - substitui pelo nome do campo em que ocorreu o problema de validação (veja atributos ClassName e FieldName da classe RFWValidationException)
  • ${classname} - substitui pele nome da classe em que a falha de validação ocorreu
  • ${cause} - substitui pelo CannonicalName da exception que causou a validação. Note que não é da própria RFWValidationException, mas sim da Throwable passada dentro dela como causa.