- O que é interceptor?
- Passos para criação do interceptor BeanValidationMethod
- Passo 1 – Criação da nova annotation BeanValidationMethod
- Passo 2 -Criação do Interceptor
- Passo 2.1 – Declaração da classe e annotations iniciais
- Passo 2.2 – Implementação do método base
- Passo 2.3 – Inserir o código comum dentro do método base
- Passo 3 – Adicionar o interceptor no arquivo beans.xml
- Passo 4 – Utilizar a annotation nos lugares desejados
- finnaly{
Olá Pessoal, tudo bom?
No artigo de hoje vamos fazer um passo a passo da construção de um interceptor chamado BeanValidationMethod, que servirá para validar as annotations Bean Validation dos parâmetros de um método interceptado. Veja na continuação…
O que é interceptor?
Se você não sabe o que é um interceptor dá uma olhada nesse artigo.
Passos para criação do interceptor BeanValidationMethod
A primeira coisa que deve ser pensada ao criar um interceptor é quais atividades comuns ele irá realizar. No caso do BeanValidationMethod em vários trechos do código existem validações dos parâmetros de um método verificando nulidade, tamanho de Strings entre outros. Assim esse trecho de validação pode ser modificado para que possa ser utilizado as annotations da biblioteca Bean Validation diretamente nos parâmetros. Esse interceptor se utiliza de duas alterações básicas no código. A primeira é que a validação estará no interceptor e a segunda é a necessidade de inserir as annotations nos parâmetros dos métodos que serão anotados.
Agora vamos fazer os 4 passos básicos para a criação de um interceptor:
- Criar uma annotation própria para identificar o interceptor
- Criar a classe que implementa o interceptor
- Adicionar o interceptor no arquivo beans.xml
- Utilizar a nova annotation no trecho de código desejado
Passo 1 – Criação da nova annotation BeanValidationMethod
No package desejado, por exemplo br.com.mauda.seminario.cientificos.interceptor, crie uma annotation chamada BeanValidationMethod, conforme o código abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package br.com.mauda.seminario.cientificos.interceptor; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.interceptor.InterceptorBinding; @InterceptorBinding @Target({ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface BeanValidationMethod { } |
Algumas explicações:
- A annotation @InterceptorBinding indica que essa annotation está vinculada a um interceptor.
- A annotation @Target indica em quais estruturas do java a annotation pode ser utilizada. No nosso exemplo, pode ser utilizada para anotar métodos (method) e classes (type)
- A annotation @Retention indica quando a JVM pode descartar a annotation. Existem 3 tipos, Class, Runtime e Source. Como o Java possui 3 fases de compilação, Código -> byteCodes -> Execução. Cada um desses 3 tipos está vinculado a uma fase desta. Como queremos que a annotation permaneça mesmo após a execução, escolhemos a constante RUNTIME.
Passo 2 -Criação do Interceptor
Nesse passo a classe que faz o trabalho do interceptor será criada.
Passo 2.1 – Declaração da classe e annotations iniciais
Primeiro a classe deve ser criada.
Após inserir na declaração da classe a annotation@Interceptor, a qual indica que a classe é uma interceptor para o CDI.
Por fim inserir a annotation recém criada @BeanValidationMethod.
O código abaixo mostra como ficou a classe:
1 2 3 4 5 6 7 8 9 |
package br.com.mauda.seminario.cientificos.interceptor; import javax.interceptor.Interceptor; @Interceptor @BeanValidationMethod public class BeanValidationMethodInterceptor { } |
Passo 2.2 – Implementação do método base
Esse próximo sub-passo é implementar o método que irá realizar o código comum antes de chamar o método original.
O método pode ter qualquer nome, no caso aqui colocamos manage. O mais importante aqui é este possuir apenas um parâmetro do tipo InvocationContext, estar annotado com @AroundInvoke e lançar uma Exception no caso de exceções.
O código abaixo mostra como ficou a classe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package br.com.mauda.seminario.cientificos.interceptor; import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; @Interceptor @BeanValidationMethod public class BeanValidationMethodInterceptor { @AroundInvoke public Object manage(InvocationContext ctx) throws Exception { } } |
Passo 2.3 – Inserir o código comum dentro do método base
Agora nesse sub-passo, vamos inserir o código de validação dentro do método criado.
Para isso vamos utilizar uma javax.validation.ValidatorFactory, linha 20, que será responsável por criar uma instância da classe javax.validation.ExecutableValidator, linha 21, para realizar a validação com o método validateParameters(), linha 22.
Caso tenha ocorrido alguma violação, linha 24, será lançada uma ConstraintViolationException, linha 25.
Caso contrário o interceptor irá chamar o método original interceptado, linha 28. A chamada via InvocationContext ao método original, utilizando o método proceed(). Essa linha irá chamar o método que foi interceptado pelo interceptor. E com isso está encerrado o código dessa classe.
O código abaixo mostra como ficou a classe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package br.com.mauda.seminario.cientificos.interceptor; import java.util.Set; import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.Validation; import javax.validation.ValidatorFactory; import javax.validation.executable.ExecutableValidator; @Interceptor @BeanValidationMethod public class BeanValidationMethodInterceptor { @AroundInvoke public Object manage(final InvocationContext ic) throws Exception { ValidatorFactory dfv = Validation.buildDefaultValidatorFactory(); ExecutableValidator validator = dfv.getValidator().forExecutables(); Set<ConstraintViolation<Object>> violations = validator.validateParameters(ic.getTarget(), ic.getMethod(), ic.getParameters()); if (!violations.isEmpty()) { throw new ConstraintViolationException(violations); } return ic.proceed(); } } |
Passo 3 – Adicionar o interceptor no arquivo beans.xml
Esse passo irá adicionar o interceptor dentro do arquivo beans.xml.
Para adicionar é necessário utilizar a tag <interceptors> e dentro dessa tag colocar uma tag <class> com o package completo mais o nome da classe Interceptor e não a annotation.
Caso seja necessário adicionar mais interceptor, apenas adicione mais uma tag <class> dentro da tag <interceptors> da mesma forma que a primeira.
As linhas destacadas abaixo mostram essas modificações:
1 2 3 4 5 6 7 8 9 |
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all"> <interceptors> <class>br.com.mauda.seminario.cientificos.interceptor.BeanValidationMethodInterceptor</class> </interceptors> </beans> |
Passo 4 – Utilizar a annotation nos lugares desejados
Por fim agora é só utilizar a annotation criada nos métodos desejados para que estes sejam interceptados e seu parâmetro validado, como mostra o trecho de código abaixo:
1 2 3 4 5 6 7 8 9 |
//Importando a annotation @BeanValidationMethod import br.com.mauda.seminario.cientificos.interceptor.BeanValidationMethod; // Utilizando no método desejado @BeanValidationMethod public void insert(@NotNull Musica musica) { //Codigo do método insert } |
finnaly{
Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!
Até um próximo post!
Leave a Reply