Comprendre les meilleures pratiques de l’API Java

Adobe Experience Manager (AEM) repose sur une riche pile de logiciels open source qui expose de nombreuses API Java à utiliser pendant le développement. Cet article explore les principales API et explique quand et pourquoi elles doivent être utilisées.

AEM est basé sur 4 jeux d'API Java Principaux.

  • Adobe Experience Manager (AEM)

    • abstractions de produits telles que pages, ressources, workflows, etc.
  • Apache SlingWeb Framework

    • abstractions REST et basées sur les ressources telles que ressources, mappages de valeurs et requêtes HTTP.
  • JCR (Apache Jackrabbit Oak)

    • Expressions de données et de contenu telles que noeud, propriétés et sessions.
  • OSGi (Apache Felix)

    • Les abstractions du conteneur d’applications OSGi telles que les services et les composants (OSGi).

API Java préférence "règle de base"

La règle générale consiste à préférer les API/abstractions dans l’ordre suivant :

  1. AEM
  2. Sling
  3. JCR
  4. OSGi

Si une API est fournie par AEM, préférez-la à Sling, JCR et OSGi. Si AEM ne fournit pas d’API, préférez Sling au JCR et OSGi.

Cet ordre est une règle générale, ce qui signifie qu'il existe des exceptions. Les raisons acceptables pour rompre avec cette règle sont les suivantes :

  • Exceptions bien connues, comme décrit ci-dessous.

  • La fonctionnalité requise n'est pas disponible dans une API de niveau supérieur.

  • Fonctionner dans le contexte du code existant (code de produit personnalisé ou AEM) qui utilise lui-même une API moins prisée, et le coût de déplacement vers la nouvelle API est injustifiable.

    • Il est préférable d’utiliser systématiquement l’API de niveau inférieur plutôt que de créer un mélange.

API AEM

Les API AEM fournissent des abstractions et des fonctionnalités spécifiques aux cas d’utilisation produits.

Par exemple, les API AEM PageManager et Page fournissent des abstractions pour les noeuds cq:Page dans AEM qui représentent des pages Web.

Bien que ces noeuds soient disponibles via les API Sling en tant que ressources et les API JCR en tant que noeuds, les API AEM fournissent des abstractions pour les cas d’utilisation courants. L’utilisation des API AEM permet d’assurer un comportement cohérent entre AEM le produit, ainsi que des personnalisations et des extensions pour les AEM.

com.adobe.* par rapport à com.day.* API

AEM API ont une préférence intra-package, identifiée par les packages Java suivants, par ordre de préférence :

  1. com.adobe.cq
  2. com.adobe.granite
  3. com.day.cq

com.adobe.cq prend en charge les cas d’utilisation de produits, tandis que com.adobe.granite prend en charge les cas d’utilisation de plateformes inter-produits, tels que les processus ou les tâches (qui sont utilisés entre les produits : AEM Assets, Sites, etc.).

com.day.cq contient des API "d’origine". Ces API traitent des abstractions et fonctionnalités de base qui existaient avant et/ou autour de l'acquisition par le Adobe de [!DNL Day CQ]. Ces API sont prises en charge et ne doivent pas être évitées, à moins que com.adobe.cq ou com.adobe.granite ne fournissent une alternative (plus récente).

De nouvelles abstractions telles que Content Fragments et Experience Fragments sont construites dans l'espace com.adobe.cq plutôt que com.day.cq décrit ci-dessous.

API de requête

AEM prend en charge plusieurs langues de requête. Les trois langues principales sont JCR-SQL2, XPath et AEM Requête Builder.

Le plus important est de maintenir un langage de requête cohérent dans toute la base de code, afin de réduire la complexité et les coûts de compréhension.

Tous les langages de requête ont effectivement les mêmes profils de performance, car Apache Oak les transpile en JCR-SQL2 pour l'exécution finale de la requête, et le temps de conversion en JCR-SQL2 est négligeable par rapport au temps de requête lui-même.

L’API préférée est AEM Requête Builder, qui est l’abstraction de niveau supérieur et fournit une API robuste pour construire, exécuter et récupérer les résultats pour les requêtes, et fournit les éléments suivants :

ATTENTION

AEM l'API QueryBuilder fuit un objet ResourceResolver. Pour atténuer cette fuite, suivez cet exemple de code.

Slingles API ;

Sling Apacheis est le cadre web RESTful qui sous-tend AEM. Sling fournit un routage de requête HTTP, modélise les noeuds JCR en tant que ressources, fournit un contexte de sécurité, et bien plus encore.

Sling Les API ont l'avantage supplémentaire d'être créées pour l'extension, ce qui signifie qu'il est souvent plus facile et plus sûr d'augmenter le comportement des applications créées à l'aide d' Sling API que les API JCR moins extensibles.

Utilisations courantes des API Sling

API JCR

Les API JCR (Java Content Repository) 2.0 font partie d’une spécification pour les implémentations JCR (dans le cas d’AEM, Apache Jackrabbit Oak). Toutes les implémentations JCR doivent se conformer à ces API et les implémenter. Il s’agit donc de l’API de niveau le plus bas pour interagir avec le contenu AEM.

Le JCR lui-même est un AEM de banque de données NoSQL hiérarchisé/basé sur une arborescence utilisé comme référentiel de contenu. Le JCR dispose d’une vaste gamme d’API prises en charge, allant du contenu CRUD à l’interrogation de contenu. Malgré cette API robuste, il est rare qu'elles soient préférées à l'AEM de niveau supérieur et aux abstractions Sling.

Préférez toujours les API JCR plutôt que les API Apache Jackrabbit Oak. Les API JCR sont destinées à interagir avec un référentiel JCR, tandis que les API Oak sont destinées à implémenter un référentiel JCR.

Les idées reçues sur les API JCR

Bien que le JCR soit AEM référentiel de contenu, ses API ne sont PAS la méthode préférée pour interagir avec le contenu. Préférez plutôt les API AEM (Page, Ressources, Balise, etc.) ou les API de ressources Sling car elles fournissent de meilleures abstractions.

ATTENTION

L’utilisation généralisée des interfaces Session et Noeud des API JCR dans une application AEM est à l’odorat du code. Assurez-vous que les API Sling ne doivent pas être utilisées à la place.

Utilisations courantes des API JCR

API OSGi

Il y a peu de chevauchement entre les API OSGi et les API de niveau supérieur (AEM, Sling et JCR), et la nécessité d'utiliser les API OSGi est rare et nécessite un haut niveau d'expertise en développement AEM.

OSGi et API Apache Felix

OSGi définit une spécification que tous les conteneurs OSGi doivent implémenter et respecter. AEM mise en oeuvre OSGi, Apache Felix, fournit également plusieurs de ses propres API.

  • Préférez les API OSGi (org.osgi) sur les API Apache Felix (org.apache.felix).

Utilisations courantes des API OSGi

Exceptions à la règle

Voici quelques exceptions courantes aux règles définies ci-dessus.

API AEM Asset

  • Préférez com.day.cq.dam.api par com.adobe.granite.asset.api.

    • Bien que les com.day.cq API Ressources offrent davantage d'outils complémentaires aux cas d'utilisation de la gestion des ressources AEM.
    • Les API Granite Assets prennent en charge les cas d’utilisation de la gestion des ressources de bas niveau (version, relations).

API de requête

  • AEM QueryBuilder ne prend pas en charge certaines fonctions de requête telles que suggestions, les indicateurs d'orthographe et d'index parmi d'autres fonctions moins courantes. Pour requête avec ces fonctions, JCR-SQL2 est préférable.

Sling Enregistrement du servlet

  • Sling enregistrement de servlet, préférez les annotations OSGi DS 1.2 avec @ SlingServletResourceTypesover @SlingServlet

Sling Enregistrement du filtre

  • Sling enregistrement de filtre, préférez les annotations OSGi DS 1.2 avec @ SlingServletFilterover @SlingFilter

Extraits de code utiles

Les extraits de code Java suivants illustrent les meilleures pratiques relatives aux cas d’utilisation courants à l’aide des API décrites. Ces extraits illustrent également comment passer d’API moins préférées à des API plus préférées.

Session JCR à Sling ResourceResolver

Résolveur de ressources Sling à fermeture automatique

Depuis AEM 6.2, le ResourceResolver Sling est AutoClosable dans une instruction try-with-resources. En utilisant cette syntaxe, un appel explicite à resourceResolver .close() n'est pas nécessaire.

@Reference
ResourceResolverFactory rrf;
...
Map<String, Object> authInfo = new HashMap<String, Object>();
authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, jcrSession);

try (ResourceResolver resourceResolver = rrf.getResourceResolver(authInfo)) {
    // Do work with the resourceResolver
} catch (LoginException e) { .. }

Sling ResourceResolver fermé manuellement

ResourceResolvers peut être fermé manuellement dans un bloc finally si la technique de fermeture automatique décrite ci-dessus ne peut pas être utilisée.

@Reference
ResourceResolverFactory rrf;
...
Map<String, Object> authInfo = new HashMap<String, Object>();
authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, jcrSession);

ResourceResolver resourceResolver = null;

try {
    resourceResolver = rrf.getResourceResolver(authInfo);
    // Do work with the resourceResolver
} catch (LoginException e) {
   ...
} finally {
    if (resourceResolver != null) { resourceResolver.close(); }
}

Chemin d'accès JCR à Sling Resource

Resource resource = ResourceResolver.getResource("/path/to/the/resource");

Noeud JCR à Sling Resource

Resource resource = resourceResolver.getResource(node.getPath());

Sling Resource à AEM ressource

Approche recommandée

DamUtil.resolveToAsset(..)résout toute ressource sous l'objet dam:Asset d'actif en montant l'arborescence si nécessaire.

Asset asset = DamUtil.resolveToAsset(resource);

Approche alternative

L'adaptation d'une ressource à un actif requiert que la ressource elle-même soit le noeud dam:Asset.

Asset asset = resource.adaptTo(Asset.class);

Sling Page Ressource vers AEM

Approche recommandée

pageManager.getContainingPage(..) résout toute ressource sous l'objet Page cq:Page en montant l'arborescence si nécessaire.

PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page page = pageManager.getContainingPage(resource);
Page page2 = pageManager.getContainingPage("/content/path/to/page/jcr:content/or/component");

Autre approche

L'adaptation d'une ressource à une page requiert que la ressource elle-même soit le noeud cq:Page.

Page page = resource.adaptTo(Page.class);

Propriétés de la page AEM lus

Utilisez les méthodes getters de l'objet Page pour obtenir des propriétés bien connues (getTitle(), getDescription(), etc.) et page.getProperties() pour obtenir le [cq:Page]/jcr:content ValueMap pour récupérer d'autres propriétés.

Page page = resource.adaptTo(Page.class);
String title = page.getTitle();
Calendar value = page.getProperties().get("cq:lastModified", Calendar.getInstance());

Lecture des propriétés de métadonnées AEM fichier

L’API Asset fournit des méthodes pratiques pour lire les propriétés à partir du noeud [dam:Asset]/jcr:content/metadata. Notez qu’il ne s’agit pas d’un ValueMap, le 2ème paramètre (valeur par défaut et casting de type automatique) n’est pas pris en charge.

Asset asset = resource.adaptTo(Asset.class);
String title = asset.getMetadataValue("dc:title");
Calendar lastModified = (Calendar) asset.getMetadata("cq:lastModified");

Sling Resource propriétés

Lorsque des propriétés sont stockées dans des emplacements (propriétés ou ressources relatives) auxquels les API AEM (Page, Asset) ne peuvent pas accéder directement, les ressources Sling et les zones ValueMaps peuvent être utilisées pour obtenir les données.

ValueMap properties = resource.getValueMap();
String value = properties.get("jcr:title", "Default title");
String relativeResourceValue = properties.get("relative/propertyName", "Default value");

Dans ce cas, l'objet AEM peut être converti en Sling Resource pour localiser efficacement la propriété ou la sous-ressource souhaitée.

AEM page à Sling Resource

Resource resource = page.adaptTo(Resource.class);

AEM actif à Sling Resource

Resource resource = asset.adaptTo(Resource.class);

Écrire des propriétés à l'aide de Sling's ModifiableValueMap

Utilisez Sling de ModifiableValueMap pour écrire des propriétés sur les noeuds. Ceci ne peut écrire que sur le noeud immédiat (les chemins de propriété relatifs ne sont pas pris en charge).

Notez que l'appel à .adaptTo(ModifiableValueMap.class) nécessite des autorisations d'écriture sur la ressource, sinon il retournera null.

ModifiableValueMap properties = resource.adaptTo(ModifiableValueMap.class);

properties.put("newPropertyName", "new value");
properties.put("propertyNameToUpdate", "updated value");
properties.remove("propertyToRemove");

resource.getResourceResolver().commit();

Création d’une page AEM

Utilisez toujours PageManager pour créer des pages au fur et à mesure qu'il utilise un modèle de page, est nécessaire pour définir et initialiser correctement les pages dans AEM.

String templatePath = "/conf/my-app/settings/wcm/templates/content-page";
boolean autoSave = true;

PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
pageManager.create("/content/parent/path", "my-new-page", templatePath, "My New Page Title", autoSave);

if (!autoSave) { resourceResolver.commit(); }

Créer une ressource Sling

ResourceResolver prend en charge les opérations de base pour la création de ressources. Lors de la création d’abstractions de niveau supérieur (AEM pages, ressources, balises, etc.) utiliser les méthodes fournies par leurs gestionnaires respectifs.

resourceResolver.create(parentResource, "my-node-name", new ImmutableMap.Builder<String, Object>()
           .put("jcr:primaryType", "nt:unstructured")
           .put("jcr:title", "Hello world")
           .put("propertyName", "Other initial properties")
           .build());

resourceResolver.commit();

Supprimer une ressource Sling

ResourceResolver prend en charge la suppression d'une ressource. Lors de la création d’abstractions de niveau supérieur (AEM pages, ressources, balises, etc.) utiliser les méthodes fournies par leurs gestionnaires respectifs.

resourceResolver.delete(resource);

resourceResolver.commit();

Sur cette page

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free