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:
- AEM
- Sling
- JCR
- 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:
com.adobe.cq
com.adobe.granite
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:
-
Eenvoudige, parameterized vraagbouw (vraagparams die als Kaart worden gemodelleerd)
-
Eigen Java™ API en HTTP APIs
-
AEM voorspeltondersteunend gemeenschappelijke vraagvereisten
-
Uitbreidbare API, die voor de ontwikkeling van douane vraagpredikatentoestaat
-
JCR-SQL2 en XPath kunnen direct via Sling worden uitgevoerden JCR APIs, terugkerend resultaten a Sling Middelenof Knooppunten JCR, respectievelijk.
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
-
De toegang tot van knopen JCR als Sling Resourcesen de toegang tot van hun gegevens via ValueMaps.
-
Het verstrekken van veiligheidscontext via ResourceResolver.
-
Creërend en verwijderend middelen via ResourceResolver creeer/beweeg/exemplaar/schrapt methodes.
-
Het bijwerken eigenschappen via ModifyingValueMap.
-
Bouwstenen voor aanvraagverwerking maken
-
Asynchrone bouwstenen voor werkverwerking
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.
Veelvoorkomende toepassingen van JCR API's
-
JCR-observatie (luisteren naar JCR-gebeurtenissen)
-
Diepknoopstructuren maken
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
-
OSGi-annotaties voor het declareren van OSGi-diensten en -componenten.
- Voorkeur OSGi de Verklarende Diensten (DS) 1.2 Annotatiesover Felix SCR Annotationsvoor het verklaren van de diensten OSGi en componenten
-
OSGi APIs voor dynamisch in-code un/registering OSGi diensten/componenten.
- Het gebruik van OSGi DS 1.2-annotaties verdient de voorkeur wanneer voorwaardelijk OSGi Service/Component management niet nodig is (wat meestal het geval is).
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.api
overcom.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).
- Hoewel de Assets API's van
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 servlet registratie, verkies OSGi DS 1.2 aantekeningen met @SlingServletResourceTypesover
@SlingServlet
Sling Filterregistratie sling-filter-registration
- Sling filterregistratie, verkies OSGi DS 1.2 aantekeningen met @SlingServletFilterover
@SlingFilter
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();