
![[8.5.5.6 ou ultérieure]](../ng_v8556.gif)
Intégration de JAX-RS 2.0 à EJB et CDI
JAX-RS 2.0 dans Liberty s'intègre à Enterprise JavaBeans (EJB) et Contexts and Dependency Injection (CDI).
Pour que JAX-RS 2.0 soit compatible avec les beans d'entreprise, vous devez utiliser @Path pour annoter la classe d'un bean et la convertir en une classe de ressources racine.
Avec l'intégration à EJB, vous pouvez annoter les beans EJB afin de les exposer en tant que noeuds finaux REST. Vous pouvez aussi utiliser les fonctions JTA et les fonctions de sécurité de EJB. JAX-RS 2.0 in Liberty prend en charge l'utilisation de session sans état et de beans de session singleton en tant que classes de ressources racines, fournisseurs et sous-classes d'application. Avec l'intégration à CDI, vous pouvez annoter les beans CDI ou les beans gérés en tant que noeuds finaux REST et utiliser l'injection CDI pour les services Web. JAX-RS 2.0 in Liberty prend en charge les beans de style CDI en tant que classes de ressources racines, fournisseurs et sous-classes d'application. Les fournisseurs et les sous-classes d'application doivent être des singletons ou utiliser la portée d'applicatio. La spécification CDI facilite l'intégration de composants Java™ EE de différents types. Elle fournit un mécanisme commun pour l'injection de composant comme les EJB ou les beans gérés dans d'autres composants tels que JSP ou autre EJB.
- Pour un bean de session sans état, utilisez l'annotation @Stateless
comme illustré dans l'exemple suivant :
@Stateless @Path("stateless-bean") public class StatelessResource {...}
- Pour un bean singleton, utilisez l'annotation @Singleton
comme illustré dans l'exemple suivant :
@Singleton @Path("singleton-bean") public class SingletonResource {...}
@ApplicationScoped
@Path("/ApplicationScopedResource")
public class ApplicationScopedResource {
private @Inject
SimpleBean injected;
...
}
Restrictionss relatives à JAX-RS 2.0 avec EJB et CDI
JAX-RS 2.0 in Liberty présente quelques restrictions :
- Si vous utilisez EJB en tant que ressource, fournisseur ou application JAX-RS, vous ne pouvez pas utiliser l'injection @Context sur le constructeur du bean EJB. EJB avec un constructeur par défaut ne peut en effet être utilisé que pour JAX-RS en fonction de la spécification EJB et JAX-RS.
- Si vous utilisez une annotation EJB ou CDI dans une classe Java, mais que la fonction Liberty pour EJB (ejbLite-3.2, par exemple) ou CDI (cdi-1.0, par exemple) n'est pas configurée dans le fichier server.xml, ce qui signifie qu'il n'y a pas de prise en charge EJB ou CDI dans l'exécution Liberty, alors le moteur JAX-RS 2.0 utilise la classe Java en tant que classe POJO.
- Si une classe Application n'implémente aucune interface ou si elle comporte
l'annotation @Localbean, elle est considérée comme un fournisseur EJB ; si elle
implémente des interfaces locales ou POJO, elle n'est pas considérée comme un fournisseur EJB.
- Pour un fournisseur :
- Si une classe implémente des interfaces de fournisseur POJO uniquement sans l'annotation @Local, elle est considérée comme un fournisseur EJB valide.
- Si une classe comporte l'annotation @LocalBean et si elle implémente l'interface de fournisseur POJO, elle est considérée comme un fournisseur EJB valide.
- Si une classe a l'interface locale avec l'annotation @Local, l'interface locale est une interface de fournisseur. Si cette classe implémente l'interface de fournisseur, il s'agit d'un fournisseur EJB valide.
- Si une classe a une interface avec l'annotation @Local et si
l'interface locale n'est pas une interface de fournisseur, il ne s'agit pas d'un fournisseur valide.
La raison est que dans ce cas, le conteneur EJB peut générer un raccord EJB pour l'interface locale uniquement au lieu de l'interface de fournisseur POJO.
- Si une classe comporte l'annotation @Local uniquement qui fait référence à une interface de fournisseur, et si elle n'implémente pas cette interface de fournisseur, alors il ne s'agit pas d'un fournisseur valide conformément à la spécification JAX-RS 2.0 : un fournisseur est une classe qui implémente une ou plusieurs interfaces JAX-RS qui sont introduites dans cette spécification et qui peuvent être annotées avec @Provider pour une reconnaissance automatique.
- Pour la ressource :
- Si une ressource basée sur EJB n'implémente aucune interface, toutes les méthodes qui sont déclarées dans cette classe sont disponibles en tant que ressources JAX-RS.
- Si une ressource basée sur EJB implémente une interface (locale ou POJO), toutes les méthodes qui sont déclarées dans cette interface sont disponibles en tant que ressources JAX-RS.
- Si une ressource basée sur EJB implémente plusieurs interfaces,
- Si toutes les interfaces sont des interfaces POJO sans l'annotation @Local, toutes les méthodes qui sont déclarées dans l'interface sont disponibles en tant que ressources JAX-RS.
- Si toutes les interfaces sont des interfaces locales avec l'annotation @Local, toutes les méthodes qui sont déclarées dans l'interface sont disponibles en tant que ressources JAX-RS.
- Si certaines interfaces sont des interfaces locales avec l'annotation @Local alors que d'autres ne sont pas des interfaces locales, seules les méthodes déclarées dans les interfaces locales sont disponibles en tant que ressources JAX-RS. La raison est que le conteneur EJB peut générer un raccord EJB pour les interfaces locales uniquement dans ce scénario.
- Si la ressource basée sur EJB comporte l'annotation @LocalBean, toutes les méthodes qui sont déclarées dans la classe sont disponibles en tant que ressource JAX-RS.
- Si une ressource basée sur EJB implémente une interface, la méthode de ressource JAX-RS doit être déclarée dans l'interface. Si l'interface est un fournisseur qui ne peut pas être modifié, alors vous devez créer une nouvelle interface pour que la classe de ressource puisse ajouter la méthode de ressource. Sinon, elle n'est pas ceonsidérée comme une ressource EJB.
- Pour un fournisseur :
- Si une classe de ressources avec l'annotation @Path implémente l'interface de fournisseur JAX-RS ou si elle se déclare avec l'annotation @Provider, cette classe fonctionne alors en tant que ressource et fournisseur. Dans ce cas, par défaut, le moteur JAX-RS 2.0 utilise une seule instance de cette classe qui est partagée par la ressource et le fournisseur, et le cycle de vie de l'instance est un singleton.
- Si une classe est enregistrée dans les méthodes getClasses et getSingletons de la classe d'application, alors le moteur JAX-RS 2.0 utilise par défait l'instance de la méthode getSingletons et ignore l'enregistrement dans la méthode getClasses.
- Si une ressource RESTful est aussi un bean géré par CDI et si sa portée est javax.enterprise.context.Dependent, la méthode PreDestroy ne peut pas être appelée en raison de la restriction CDI.
Traitement asynchrone
Vous pouvez utiliser la technique de traitement asynchrone dans JAX-RS 2.0 pour traiter les unités d'exécution. Le traitement asynchrone est pris en charge à la fois dans l'API client et dans API serveur. Pour plus d'informations sur le traitement asynchrone, voir le chapitre 8 de la spécification JSR-339 Java API for RESTful ("Spécification").
Le code suivant affiche le traitement asynchrone dans l'API client :
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://example.org/customers/{id}");
target.resolveTemplate("id", 123).request().async().get(
new InvocationCallbackCustomer() {
@Override
public void completed(Customer customer) {
// Do something
}
@Override
public void failed(Throwable throwable) {
// Process error
}
});
The following code shows asynchronous processing in the Server API:
@Path("/async")
public class MyResource{
@GET
public void getAsync(@Suspended final AsyncResponse asyncResponse){
CompletionCallback callBack = new CompletionCallback(){
@Override
public void onComplete(Throwable throwable) {
...
}
};
asyncResponse.register(callBack);
asyncResponse.resume("some Response");
}
}
@Stateless
@Path("/")
class EJBResource {
@GET @Asynchronous
public void longRunningOp(@Suspended AsyncResponse ar) {
executeLongRunningOp();
ar.resume("Hello async world!");
}
}
La gestion des unités d'exécution explicite n'est pas nécessaire
dans ce cas car cela est sous le contrôle du conteneur d'EJB. La réponse
est générée par la reprise d'appel sur l'élément AsyncResponse injecté.
Par
conséquent, le type de retour longRunningOp est nul.Cycle de vie du bean JAX-RS 2.0 et du bean EJB
Application | JAX-RS 2.0 | EJB | Résultat |
---|---|---|---|
Ressource | perRequest | Sans état | Sans état |
perRequest | Singleton | Singleton | |
Singleton | Sans état | Sans état | |
Singleton | Singleton | Singleton | |
Fournisseur | Singleton | Sans état | Sans état |
Singleton | Singleton | Singleton |
Cycle de vie de la portée JAX-RS 2.0 et de la portée CDI
Application | Portée JAX-RS 2.0 | Annotation de portée CDI | Résultat |
---|---|---|---|
Ressource | perRequest | @ApplicationScoped | Singleton |
perRequest | @RequestScoped | perRequest | |
perRequest | @Dependent | perRequest | |
perRequest | @SessionScoped | Session | |
perRequest | perRequest | ||
Singleton | @ApplicationScoped | Singleton | |
Singleton | @RequestScoped | perRequest | |
Singleton | @Dependent | Singleton | |
Singleton | @SessionScoped | Session | |
Singleton | Singleton | ||
Fournisseur | Singleton | @ApplicationScoped | Singleton |
Singleton | @RequestScoped | Singleton | |
Singleton | @Dependent | Singleton | |
Singleton | @SessionScoped | Singleton | |
Singleton | Singleton |
Messages de conflit du cycle de vie de la portée JAX-RS 2.0 et de la portée CDI
Les messages d'avertissement ci-après s'affichent lorsque le cycle de vie de portée de JAX-RS 2.0 et CDI sont en conflit. Il s'agit de messages d'avertissement et aucune action n'est requise.
Ce message s'affiche si la portée de ressource JAXRS-2.0 ne correspond pas à la portée CDI et si l'instance de ressource existe dans CDI, de sorte que Liberty obtient l'instance de ressource de CDI. L'instance inclut pas l'injection CDI si elle provient de JAXRS.CWWKW1001W: La portée {1} de JAXRS-2.0 Resource {0} ne correspond pas à la portée CDI {2}. Liberty obtient l'instance de ressource de {3}.
Ce message s'affiche parce que l'instance de fournisseur est Singleton uniquement. Liberty obtient l'instance de fournisseur de CDI si la portée CDI du fournisseur est de type Dependent ou ApplicationScoped. L'instance inclut pas l'injection CDI si elle provient de JAXRS.CWWKW1002W: La portée CDI de JAXRS-2.0 Provider {0} est {1}. Liberty obtient l'instance de fournisseur de {2}.