Vous pouvez utiliser JDCI (Java™ Contexts
and Dependency Injection) pour écrire des intercepteurs et des décorateurs pour les types de ressource JAX-RS (Java API for RESTful Web
Services). Par exemple, vous pouvez utiliser les fonctions d'intercepteur et de décorateur de JCDI pour journaliser des appels pour une classe particulière ou pour effectuer un contrôle de sécurité avant d'appeler une méthode lors de l'utilisation d'applications Web JCDI avec JAX-RS.
Pourquoi et quand exécuter cette tâche
Il existe deux méthodes permettant d'ajouter des aspects transversaux à votre application. Les liaisons d'intercepteur ont besoin d'une annotation personnalisée. L'annotation est utilisée pour identifier les méthodes qui doivent être interceptées. Les décorateurs implémentent le type de base. Ensuite, à l'aide d'une instance injectée @javax.decorator.Decorator, vous pouvez implémenter votre logique spéciale autour des appels au délégué injecté.
Procédure
- Créez une annotation pour indiquer qu'une méthode est interceptée. Cette annotation SecurityChecked spécifie une méthode dans laquelle des informations de sécurité sont vérifiées. L'exemple suivant illustre une annotation personnalisée avec une méthode interceptée :
package com.example.jaxrs;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;
@Inherited
@InterceptorBinding
@Target( {ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SecurityChecked {
}
- Créez votre classe de ressources JAX-RS et annotez les méthodes que vous souhaitez intercepter avec l'annotation@com.example.jaxrs.SecurityChecked. L'exemple suivant illustre une classe de ressources JAX-RS avec une méthode interceptée :
package com.example.jaxrs;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
@Path("exampleInterceptor")
@RequestScoped
public class MyResourceBean {
@GET
@com.example.jaxrs.SecurityChecked
public String echo(String hello) {
return "Hello world!";
}
}
- Ecrivez une classe d'intercepteur annotée avec l'annotation @javax.interceptor.Interceptor et avec le marqueur d'intercepteur @com.example.jaxrs.SecurityChecked. Ajoutez ensuite une méthode annotée avec l'annotation @javax.interceptor.AroundInvoke avec le paramètre
javax.interceptor.InvocationContext. Vous pouvez utiliser les méthodes InvocationContext pour inspecter l'appel de méthode et déterminer si l'appel doit se poursuivre. L'exemple suivant illustre un intercepteur :
package com.example.jaxrs;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
@com.example.jaxrs.SecurityChecked
public class SecurityCheckInterceptor {
@AroundInvoke
public Object checkSecurity(InvocationContext context) throws Exception {
/* check the parameters or do a generic security check before invoking the
original method */
Object[] params = context.getParameters();
/* if security validation fails, you can throw an exception */
/* invoke the proceed() method to call the original method */
Object ret = context.proceed();
/* perform any post method call work */
return ret;
}
}
- Ajoutez un descripteur de déploiement beans.xml à votre fichier WAR d'application Web dans le répertoire WEB-INF. L'existence du fichier WEB-INF/beans.xml indique que l'archive est une archive JCDI. Vous devez ajouter des informations pour cette instance. L'exemple suivant illustre un fichier WEB-INF/beans.xml avec un intercepteur répertorié :
<?xml version="1.0 encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http://
java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.example.jaxrs.SecurityCheckInterceptor</class>
</interceptors>
</beans>
Lors des étapes précédentes, vous avez configuré une application Web pour utiliser JCDI, ajouté une annotation personnalisée pour marquer des méthodes pour l'interception et écrit un intercepteur. Lorsqu'une méthode marquée est appelée, l'intercepteur permet de déterminer si la méthode marquée doit être appelée et peut exécuter la logique supplémentaire. Vous devez répertorier les intercepteurs dans votre descripteur de déploiement beans.xml.Dans les étapes restantes, vous créez et activez un décorateur dans une application Web JCDI. Les liaisons d'intercepteur nécessitent une annotation pour marquer les méthode pour interception. Les décorateurs implémentent le type de base et peuvent encapsuler les appels.
- Recherchez ou créez le type de base devant être implémenté par le décorateur. Par exemple, le type de base peut être une interface nommée Item.
L'exemple suivant illustre une interface commune utilisée par un décorateur :
package com.example.jaxrs;
import javax.ws.rs.GET;
public interface Item {
@GET
public String getInformation();
}
- Créez une classe de ressources JAX-RS standard implémentant le type de base. L'exemple suivant illustre une classe de ressources JAX-RS qui sera décorée :
package com.example.jaxrs;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Path;
@Path("decoratedresource")
@RequestScoped
public class MyItem implements Item {
public String getInformation() {
/* return some information */
}
}
- Créez une classe de décorateur. La classe de décorateur doit implémenter le type de base dans lequel tous les appels sont encapsulés. Le décorateur doit être annoté avec l'annotation @javax.decorator.Decorator.
Le décorateur doit comprendre une zone spéciale, appelée point d'injection de délégué, avec le type de base. La zone peut avoir un nom de variable et doit comprendre des annotations @javax.inject.Inject et @javax.decorator.Delegate.
Cette zone est l'objet d'origine à décorer. Vous pouvez ensuite utiliser cet objet décoré dans vos appels d'implémentation.
L'exemple suivant illustre une classe de décorateur de base :
package com.example.jaxrs;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;
@Decorator
public class MyItemDecorator implements Item {
@Inject
@Delegate
private Item decoratedItem;
public String getInformation() {
/* perform some logging */
String info = decoratedItem.getInformation();
/* perform some more logging */
return info;
}
}
- Ajoutez un descripteur de déploiement beans.xml à votre fichier WAR d'application Web dans le répertoire WEB-INF. L'existence du fichier WEB-INF/beans.xml indique que l'archive est une archive JCDI. Vous devez ajouter des informations concernant les classes de décorateur actives pour cette instance. L'exemple suivant illustre un fichier WEB-INF/beans.xml avec un décorateur répertorié :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http://
java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.example.jaxrs.SecurityCheckInterceptor</class>
</interceptors>
<decorators>
<class>com.example.jaxrs.MyItemDecorator</class>
</decorators>
</beans>
Résultats
Vous avez configuré une application Web pour utiliser JCDI, créé un intercepteur de méthode pour une ressource, créé un décorateur et permis à ce dernier de décorer vos appels de méthode pour une deuxième ressource.