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 "Miniatuur"

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 aanbiedt, geeft u de voorkeur aan Sling boven 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 op 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.

Bijvoorbeeld, AEM PageManageren PaginaAPIs verstrekt abstracties voor cq:Page knopen in AEM die Web-pagina's vertegenwoordigen.

Hoewel deze knooppunten beschikbaar zijn via Sling API's als bronnen en JCR API's als knooppunten, bieden AEM API's 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

Het com.adobe.cq -pakket ondersteunt productgebruikscenario's, terwijl com.adobe.granite gebruiksscenario's voor verschillende productplatforms ondersteunt, zoals workflows of taken (die voor alle producten worden gebruikt: AEM Assets, Sites, enzovoort).

Het com.day.cq -pakket bevat 'originele' API's. Deze API's bieden oplossingen voor basisabstracties en -functies die bestonden vóór en/of rond de overname van Day CQ door Adobe. Deze API's worden ondersteund en moeten worden vermeden, tenzij com.adobe.cq - of com.adobe.granite -pakketten GEEN (nieuwer) alternatief bieden.

Nieuwe abstracties zoals Content Fragments en Experience Fragments worden in de com.adobe.cq -ruimte opgebouwd in plaats van com.day.cq hieronder.

Query-API's

AEM ondersteunt meerdere querytalen. De drie belangrijkste talen zijn JCR-SQL2, XPath, en AEM de Bouwer van de Vraag.

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

Alle vraagtalen hebben in feite de zelfde prestatiesprofielen, aangezien Apache Oak hen aan JCR-SQL2 voor definitieve vraaguitvoering overstapt, en de omzettingstijd aan JCR-SQL2 verwaarloosbaar in vergelijking met de vraagtijd zelf is.

De aangewezen API is AEM de Bouwer van de Vraag, die de hoogste niveauabstractie is en robuuste API voor het construeren, het uitvoeren, en het terugwinnen van resultaten voor vragen verstrekt, en het volgende verstrekt:

CAUTION
AEM QueryBuilder-API lekt een ResourceResolver-object. Om dit lek te verlichten, volg dit codesteekproef.

Sling API's

Apache Slingis het RESTful Webkader dat AEM steunt. Sling verstrekt HTTP- verzoek het verpletteren, modelleert knopen JCR als middelen, verstrekt veiligheidscontext, en veel meer.

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

Veelvoorkomende toepassingen van API's van Sling

JCR-API's

JCR (de Bewaarplaats van de Inhoud Java™) 2.0 APIsmaakt deel uit van een specificatie voor de implementaties van JCR (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 hebben ze maar zelden de voorkeur boven de AEM en abstracties op een hoger niveau. Sling

Geef altijd de voorkeur aan de JCR API's boven de Apache Jackrabbit Oak API's. JCR APIs is voor het in wisselwerking staan met een bewaarplaats JCR, terwijl Oak APIs voor het uitvoeren van een bewaarplaats JCR is.

Algemene misvattingen over JCR API's

Terwijl de JCR AEM opslagplaats voor inhoud , hebben de API's NIET de voorkeursmethode voor interactie met de inhoud. In plaats daarvan geeft u de voorkeur aan de API's voor AEM (Pagina, Assets, Tag, enzovoort) of Sling Resource API's omdat deze betere abstracties bieden.

CAUTION
Het brede gebruik van de Sessie- en Node-interfaces van de JCR API's in een AEM toepassing is codegeur. Zorg ervoor dat in plaats daarvan Sling -API's worden gebruikt.

Veelvoorkomende toepassingen van JCR API's

OSGi API's

Er is weinig overlapping tussen OSGi APIs en hoger-niveau APIs (AEM, Sling, en JCR), en de behoefte om OSGi APIs 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. Apache Felix, AEM OSGi-implementatie, biedt ook verschillende van zijn eigen API's.

  • Voorkeur voor OSGi APIs (org.osgi) over Apache Felix APIs (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 u werkt met OSGi-abstracties op laag niveau, zoals het definiëren of lezen in eigenschappen van OSGi-componenten, hebben de nieuwere abstracties die door org.osgi worden geboden de voorkeur boven Sling-abstracties op hoger niveau. De concurrerende Abstracties van het Sling zijn niet gemerkt als @Deprecated en suggereren het org.osgi alternatief.

Let ook op dat de definitie van de OSGi-configuratienode de voorkeur geeft aan cfg.json boven de sling:OsgiConfig -indeling.

Elementen-API's AEM

  • De voorkeur com.day.cq.dam.apiover com.adobe.granite.asset.api.

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

Query-API's

  • AEM QueryBuilder steunt bepaalde vraagfuncties zoals suggesties, spellcheck, en indexwenken onder andere minder gemeenschappelijke functies niet. Om met deze functies te vragen wordt JCR-SQL2 geprefereerd.

Sling Serverregistratie sling-servlet-registration

Sling Filterregistratie sling-filter-registration

Nuttige codefragmenten

Hieronder vindt u handige 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, is Sling ResourceResolver AutoClosable in a probeer-met-middelenverklaring. Met deze syntaxis is een expliciete aanroep van resourceResolver .close() 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 -blok 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 om element te AEM

Aanbevolen aanpak

De functie DamUtil.resolveToAsset(..) lost om het even welke middelen onder dam:Asset aan het voorwerp van Activa op door de boom naar boven te lopen zoals nodig.

Asset asset = DamUtil.resolveToAsset(resource);

Alternatieve benadering

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

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

Sling Bron voor AEM pagina

Aanbevolen aanpak

pageManager.getContainingPage(..) lost om het even welke middelen onder cq:Page aan het voorwerp van de Pagina door de boom te lopen zoals nodig.

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 alternative-approach-1

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

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

Eigenschappen van AEM pagina lezen

Gebruik de getters van het object Page om bekende eigenschappen (getTitle() , getDescription() , enzovoort) en page.getProperties() op te halen om [cq:Page]/jcr:content ValueMap te verkrijgen 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 het knooppunt [dam:Asset]/jcr:content/metadata . Dit is geen ValueMap, de tweede parameter (standaardwaarde en automatisch gegoten casting) wordt niet ondersteund.

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

Eigenschappen van het type Read Sling Resource read-sling-resource-properties

Wanneer eigenschappen worden opgeslagen op locaties (eigenschappen of relatieve bronnen) waartoe de AEM-API's (Pagina, Element) niet rechtstreeks toegang hebben, kunnen de bronnen van Sling en ValueMaps 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 kunnen vinden.

Pagina AEM naar Sling Resource

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

Element AEM naar Sling Resource

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

Eigenschappen schrijven met de functie ModisibleValueMap van Sling

Het gebruik ModifyingValueMapvan Sling {om eigenschappen aan knopen te schrijven. Dit kan alleen naar het huidige knooppunt worden geschreven (relatieve paden van eigenschappen worden niet ondersteund).

De aanroep van .adaptTo(ModifiableValueMap.class) vereist schrijfmachtigingen naar de bron, anders wordt null geretourneerd.

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 -bron maken

ResourceResolver steunt basisverrichtingen voor het creëren van middelen. Bij het maken van abstracties op een hoger niveau (AEM Pagina's, Assets, Codes, enzovoort) gebruikt u de methoden die worden geleverd door de respectievelijke managers.

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 -bron verwijderen

ResourceResolver ondersteunt het verwijderen van een resource. Bij het maken van abstracties op een hoger niveau (AEM Pagina's, Assets, Codes, enzovoort) gebruikt u de methoden die worden geleverd door de respectievelijke managers.

resourceResolver.delete(resource);

resourceResolver.commit();
recommendation-more-help
c92bdb17-1e49-4e76-bcdd-89e4f85f45e6