Red Hat Training

A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform

14.8. Intercepteurs RESTEasy

14.8.1. Interception des invocations JAX-RS

Résumé

RESTEasy peut intercepter les invocations JAX-RS et les re-router vers des objets style listener que l'on appelle des intercepteurs. Cette section couvre les descriptions de quatre types d'intercepteurs.

Exemple 14.3. Intercepteurs MessageBodyReader/Writer

Les MessageBodyReaderInterceptors et les MessageBodyWriterInterceptors peuvent être utilisés soit côté cleint, soit côté serveur. Ils sont annotés par @Provider, ainsi que par @ServerInterceptor ou @ClientInterceptor, de façon à ce que RESTEasy sache s'il doit les ajouter ou non à la liste d'intercepteurs.
Ces intercepteurs encapsulent l'invocation de MessageBodyReader.readFrom() ou de MessageBodyWriter.writeTo(). Ils peuvent être utilisés pour encapsuler les flux d'entrée ou de sortie.
Le Support RESTEasy GZIP possède des intercepteurs qui créent ou remplacent les flux d'entrée ou de sortie par défaut par un GzipOutputStream ou un GzipInputStream afin que l'encodage gzip puisse opérer. Ils peuvent également être utilisés pour ajouter les en-têtes à la réponse, ou la requête sortante côté client.
public interface MessageBodyReaderInterceptor
  {
     Object read(MessageBodyReaderContext context) throws IOException, WebApplicationException;

  }

public interface MessageBodyWriterInterceptor
  {
     void write(MessageBodyWriterContext context) throws IOException, WebApplicationException;

  }
Les intercepteurs et le MessageBodyReader ou Writer sont invoqués dans une seule pile d'appels de Java. MessageBodyReaderContext.proceed() ou MessageBodyWriterContext.proceed() est appelé pour aller vers le prochain intercepteur, ou, s'il n'y a plus d'intercepteur à invoquer, la méthode readFrom() ou writeTo() du MessageBodyReader ou du MessageBodyWriter. Cette encapsulation permet aux objets d'être modifiés avant d'aller vers le Reader ou Writer, puis d'être nettoyés, après proceed().
L'exemple ci-dessous montre un serveur côté intercepteur, qui ajoute une valeur d'en-tête à la réponse.
@Provider
@ServerInterceptor
public class MyHeaderDecorator implements MessageBodyWriterInterceptor {

    public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException
    {
       context.getHeaders().add("My-Header", "custom");
       context.proceed();
    }
}

Exemple 14.4. PreProcessInterceptor

Les PreProcessInterceptors sont exécutés après qu'une méthode de ressource JAX-RS ait été trouvée pour l'invocation, mais avant l'invocation réelle. Ils sont annotés avec @ServerInterceptor et exécutent en séquence.
Ces interfaces ne sont pas utilisables sur le serveur. Elles peuvent être utilisées pour implémenter des fonctionnalités de sécurité, ou afin de préempter la demande Java. La mise en œuvre de la sécurité RESTEasy utilise ce type d'intercepteur pour abandonner les demandes avant qu'elles aient lieu si l'utilisateur ne passe pas d'autorisation. Le framework de mise en cache de RESTEasy utilise ceci également pour renvoyer des réponses mises en cache afin d'éviter une fois de plus l'invocation de méthodes.
public interface PreProcessInterceptor
    {
       ServerResponse preProcess(HttpRequest request, ResourceMethod method) throws Failure, WebApplicationException;
    }
Si la méthode preProcess() renvoie une ServerResponse, alors la méthode JAX-RS sous-jacente ne sera pas invoquée, et le runtime traitera la réponse et retournera au client. Si la méthode preProcess() ne renvoie pas une ServerResponse, la méthode JAX-RS sous-jacente sera alors invoquée.

Exemple 14.5. PostProcessInterceptors

Les PreProcessInterceptors sont exécutés après qu'une méthode de ressource JAX-RS ait été invoquée, mais avant que MessageBodyWriters ait été invoqué. Ils sont utilisés si un en-tête de réponse a besoin d'être défini quand un MessageBodyWriter n'est pas invoqué.
Ils ne peuvent être utilisés que du côté du serveur. Ils ne peuvent pas encapsuler quoi que ce soit, et sont invoqués séquentiellement.
public interface PostProcessInterceptor
  {
    void postProcess(ServerResponse response);
  }

Exemple 14.6. ClientExecutionInterceptors

Les ClientExecutionInterceptors ne sont utilisables que du côté client. Ils sont encapsulés dans l'invocation HTTP qui va vers le serveur. Ils doivent être annotés par @ClientInterceptor et @Provider. Ces intercepteurs sont exécutés après que le MessageBodyWriter, et que le ClientRequest aient été créés côté client.
Le support RESTEasy GZIP utilise des ClientExecutionInterceptors pour que l'en-tête Accept puisse contenir «gzip, deflate» avant que la demande soit envoyée. Le cache du client RESTEasy l'utilise pour vérifier si son cache contient la ressource avant qu'elle soit envoyée.
public interface ClientExecutionInterceptor
{
  ClientResponse execute(ClientExecutionContext ctx) throws Exception;
}

public interface ClientExecutionContext
{
  ClientRequest getRequest();

  ClientResponse proceed() throws Exception;
}