Aanbevolen werkwijzen voor Java API

Adobe Experience Manager (AEM) is gebaseerd op een rijke open-source softwarestack die veel Java API's beschikbaar maakt voor gebruik tijdens de ontwikkeling. In dit artikel worden de belangrijkste API's besproken en wordt aangegeven wanneer en waarom deze moeten worden gebruikt.

AEM is gebaseerd op vier primaire Java API-sets.

  • Adobe Experience Manager (AEM)

    • Productabstracties zoals pagina's, middelen, workflows, enz.
  • Apache Sling Web Framework

    • REST en op bron-gebaseerde abstracties zoals middelen, waardekaarten, en HTTP- verzoeken.
  • JCR (Apache Jackrabbit Oak)

    • Abstracties van gegevens en inhoud, zoals knooppunten, eigenschappen en sessies.
  • OSGi (Apache Felix)

    • OSGi de abstracties van de toepassingscontainer zoals de diensten en (OSGi) componenten.

Java API-voorkeursregel "thumb-regel"

De algemene regel is om de voorkeur te geven aan API's/abstracties in de volgende volgorde:

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

Als een API door AEM wordt verstrekt, verkies het over Sling, JCR en OSGi. Als AEM geen API biedt, geeft u de voorkeur Sling over JCR en OSGi.

Deze volgorde is een algemene regel, wat betekent dat er uitzonderingen bestaan. Aanvaardbare redenen om van deze regel af te wijken zijn:

  • Bekende uitzonderingen, zoals hieronder beschreven.

  • De vereiste functionaliteit is niet beschikbaar in een API van een hoger niveau.

  • Werken in de context van bestaande code (aangepaste code of AEM productcode) die zelf een minder voorkeursAPI gebruikt, en de kosten om naar de nieuwe API te gaan zijn niet te rechtvaardigen.

    • Het is beter de API op een lager niveau consequent te gebruiken dan een combinatie te maken.

API's AEM

AEM API's bieden abstracties en functionaliteit die specifiek zijn voor gebruikssituaties die in productie zijn.

AEM PageManager en Pagina API's bieden abstracties voor cq:Page knooppunten in AEM die webpagina's vertegenwoordigen.

Deze knooppunten zijn beschikbaar via Sling API's als bronnen en JCR API's als knooppunten AEM API's bieden abstracties voor veelvoorkomende gebruiksgevallen. Het gebruik van de AEM-API's zorgt voor een consistent gedrag tussen AEM product en aanpassingen en uitbreidingen die moeten worden AEM.

com.adobe.* vs com.day.* API's

AEM API's hebben een voorkeur voor een pakket, die wordt aangegeven door de volgende Java-pakketten, in volgorde van voorkeur:

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

com.adobe.cq ondersteunt productgebruiksgevallen terwijl com.adobe.granite ondersteunt toepassingen waarbij meerdere producten worden gebruikt, zoals een workflow of taken (die voor alle producten worden gebruikt): AEM Assets, sites, enz.).

com.day.cq bevat "originele" API's. Deze API's bieden oplossingen voor basisabstracties en -functies die bestonden vóór en/of rond de aankoop van Adobe Day CQ. Deze API's worden ondersteund en mogen alleen worden vermeden com.adobe.cq of com.adobe.granite bieden een (nieuwer) alternatief.

Nieuwe abstracties, zoals Content Fragments en Experience Fragments zijn ingebouwd in het com.adobe.cq ruimte in plaats van com.day.cq hieronder beschreven.

Query-API's

AEM ondersteunt meerdere querytalen. De drie belangrijkste talen zijn JCR-SQL2, XPath en AEM Query Builder.

De belangrijkste zorg is het handhaven van een verenigbare vraagtaal over de codebasis, om ingewikkeldheid en kosten te verminderen om te begrijpen.

Alle querytalen hebben in feite dezelfde prestatieprofielen als Apache Oak trans-pileert hen aan JCR-SQL2 voor definitieve vraaguitvoering, en de omzettingstijd aan JCR-SQL2 is verwaarloosbaar in vergelijking met de vraagtijd zelf.

De voorkeurs-API is AEM Query Builder, de abstractie op het hoogste niveau en biedt een robuuste API voor het maken, uitvoeren en ophalen van resultaten voor query's, en biedt de volgende mogelijkheden:

LET OP

AEM QueryBuilder-API lekt een ResourceResolver-object. Volg deze codevoorbeeld.

Sling API's

Apache Sling is het RESTful-webframework dat AEM ondersteunt. Sling verstrekt HTTP- verzoek het verpletteren, modellenJCR knopen als middelen, verstrekt veiligheidscontext, en veel meer.

Sling API's hebben het extra voordeel dat ze voor extensies worden gemaakt. Dit betekent dat het vaak eenvoudiger en veiliger is om het gedrag van toepassingen die met Sling API's die kleiner zijn dan de minder uitbreidbare JCR-API's.

Algemeen gebruik van Sling API's

JCR-API's

De API's voor JCR (Java Content Repository) 2.0 deel uitmaakt van een specificatie voor de uitvoering van het GCO (in het geval van AEM; Apache Jackrabbit Oak). Alle JCR-implementatie moet in overeenstemming zijn met deze API's en deze implementeren. Dit is dus de API op het laagste niveau voor interactie met AEM inhoud.

De JCR zelf is een hiërarchische/op boom-gebaseerde NSQL datastore AEM als zijn inhoudsbewaarplaats gebruikt. De JCR heeft een uitgebreide reeks ondersteunde API's, variërend van inhoud-CRUD tot het opvragen van inhoud. Ondanks deze robuuste API is het zeldzaam dat ze de voorkeur hebben boven de hogere AEM en Sling abstracties.

Geef altijd de voorkeur aan de JCR-API's boven de Apache Jackrabbit Oak-API's. De JCR API's zijn bedoeld voor interactie met een JCR-opslagplaats, terwijl de Eak API's bedoeld zijn voor uitvoeren een JCR-opslagplaats.

Algemene misvattingen over JCR API's

Terwijl de JCR AEM opslagplaats voor inhoud is, hebben de API's NIET de voorkeursmethode voor interactie met de inhoud. In plaats daarvan geeft u de voorkeur aan de AEM-API's (pagina, middelen, tag, enz.) of Sling Resource APIs aangezien zij betere abstracties verstrekken.

LET OP

Het brede gebruik van de Sessie- en Node-interfaces van de JCR API's in een AEM toepassing is codegeur. Zorgen Sling API's mogen niet worden gebruikt.

Veelvoorkomende toepassingen van JCR API's

  • Toegangsbeheer

  • Toegestaan beheer (gebruikers/groepen)

  • JCR-observatie (luisteren naar JCR-gebeurtenissen)

  • Diepknoopstructuren maken

    • De API's voor verkoop ondersteunen het maken van bronnen, maar de JCR API's beschikken over gebruiksvriendelijke methoden op het gebied van JcrUtils en JcrUtil dat versnelde het creëren van diepe structuren .

OSGi API's

Er is weinig overlap tussen de OSGi API's en de API's op een hoger niveau (AEM, Sling, en JCR), en de noodzaak om OSGi API's te gebruiken is zeldzaam en vereist een hoog niveau van AEM ontwikkelingsdeskundigheid.

OSGi vs Apache Felix API's

OSGi bepaalt een specificatie alle containers OSGi moeten uitvoeren en met in overeenstemming zijn. AEM OSGi-implementatie, Apache Felix, biedt ook verschillende van zijn eigen API's.

  • Voorkeur voor OSGi API's (org.osgi) via Apache Felix API's (org.apache.felix).

Veelvoorkomende toepassingen van OSGi API's

Uitzonderingen op de regel

Hieronder volgen algemene uitzonderingen op de hierboven gedefinieerde regels.

OSGi API's

Wanneer het behandelen van lage OSGi abstracties, zoals het bepalen van of het lezen in eigenschappen van de component OSGi, de nieuwere abstracties die door worden verstrekt org.osgi verdienen de voorkeur boven hogere Sling Abractions. De concurrerende Sling abstracties zijn niet gemarkeerd als @Deprecated en stelt de org.osgi alternatief.

Merk ook op de definitie van de OSGi- configuratieknooppunt verkiest cfg.json over de sling:OsgiConfig gebruiken.

Elementen-API's AEM

  • Voorkeur com.day.cq.dam.api over com.adobe.granite.asset.api.

    • Terwijl de com.day.cq De elementen-API's bieden meer gratis tools voor het AEM van gebruiksscenario's voor middelenbeheer.
    • De API's van Granite Assets ondersteunen gebruiksscenario's voor middelenbeheer op laag niveau (versie, relaties).

Query-API's

  • AEM QueryBuilder biedt geen ondersteuning voor bepaalde queryfuncties, zoals suggesties, spellingcontrole en indextips voor minder algemene functies. Om met deze functies te vragen wordt JCR-SQL2 geprefereerd.

Sling Servlet-registratie

Sling Filterregistratie

Nuttige codefragmenten

Hieronder vindt u nuttige Java-codefragmenten die tips en trucs weergeven voor veelvoorkomende toepassingen met behulp van besproken API's. Deze fragmenten tonen ook hoe u van API's met minder voorkeuren naar API's met meer voorkeuren kunt gaan.

JCR-sessie naar Sling ResourceResolver

Auto-closing Sling ResourceResolver

Sinds AEM 6.2 Sling ResourceResolver is AutoClosable in een try-with-resources instructie. Met behulp van deze syntaxis, een expliciete aanroep van resourceResolver .close() is niet nodig.

@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) { .. }

Handmatig gesloten Sling ResourceResolver

ResourceResolvers kan handmatig worden gesloten in een finally blokkeren, als de hierboven getoonde techniek voor automatisch sluiten niet kan worden gebruikt.

@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(); }
}

JCR-pad naar Sling Resource

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

JCR-knooppunt naar Sling Resource

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

Sling Resource aan AEM

Aanbevolen aanpak

DamUtil.resolveToAsset(..)lost om het even welke bron onder het dam:Asset naar het object Asset door de boomstructuur zo nodig naar boven te doorlopen.

Asset asset = DamUtil.resolveToAsset(resource);

Alternatieve benadering

Als u een resource wilt aanpassen aan een element, moet de resource zelf de dam:Asset knooppunt.

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

Sling Bron naar AEM pagina

Aanbevolen aanpak

pageManager.getContainingPage(..) lost om het even welke bron onder het cq:Page naar het object Pagina door de structuur naar boven te doorlopen.

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

Alternatieve benadering

Als u een bron wilt aanpassen aan een pagina, moet de bron zelf de cq:Page knooppunt.

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

Eigenschappen van AEM pagina lezen

Gebruik de getters van het object Pagina om bekende eigenschappen (getTitle(), getDescription(), enz.) en page.getProperties() om [cq:Page]/jcr:content ValueMap voor het ophalen van andere eigenschappen.

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

Eigenschappen van metagegevens van AEM element lezen

De API voor middelen biedt handige methoden voor het lezen van eigenschappen van de [dam:Asset]/jcr:content/metadata knooppunt. Merk op dat dit geen ValueMap is, wordt de tweede parameter (standaardwaarde, en auto-type het gieten) niet gesteund.

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

Lezen Sling Resource eigenschappen

Wanneer eigenschappen worden opgeslagen op locaties (eigenschappen of relatieve bronnen) waartoe de AEM-API's (Pagina, Element) niet rechtstreeks toegang hebben, wordt Sling De middelen en ValueMaps kunnen worden gebruikt om de gegevens te verkrijgen.

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

In dit geval moet het AEM mogelijk worden omgezet in een Sling Resource om de gewenste eigenschap of subbron efficiënt te vinden.

Pagina AEM naar Sling Resource

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

Element AEM aan Sling Resource

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

Eigenschappen schrijven met Sling's ModisibleValueMap

Gebruiken Slings ModisibleValueMap om eigenschappen naar knooppunten te schrijven. Dit kan alleen naar het huidige knooppunt worden geschreven (relatieve paden van eigenschappen worden niet ondersteund).

Noteer de oproep aan .adaptTo(ModifiableValueMap.class) schrijft toestemmingen aan het middel vereist, anders zal het ongeldig terugkeren.

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

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

resource.getResourceResolver().commit();

Een AEM pagina maken

Gebruik altijd PageManager om pagina's tot stand te brengen aangezien het een Malplaatje van de Pagina neemt, wordt vereist om Pagina's in AEM behoorlijk te bepalen en te initialiseren.

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(); }

Een Sling Resource

ResourceResolver steunt basisverrichtingen voor het creëren van middelen. Bij het maken van abstracties op een hoger niveau (AEM pagina's, elementen, tags, enzovoort) de methoden gebruiken die door hun respectieve managers zijn verstrekt.

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();

Een Sling Resource

ResourceResolver ondersteunt het verwijderen van een resource. Bij het maken van abstracties op een hoger niveau (AEM pagina's, elementen, tags, enzovoort) de methoden gebruiken die door hun respectieve managers zijn verstrekt.

resourceResolver.delete(resource);

resourceResolver.commit();

Op deze pagina