Adobe Experience Manager (AEM) bygger på en omfattande programstack med öppen källkod som visar många Java™-API:er för användning under utveckling. I den här artikeln utforskas de viktigaste API:erna och när och varför de ska användas.
AEM bygger på fyra primära Java™ API-uppsättningar.
Adobe Experience Manager (AEM)
Apache Sling Web Framework
JCR (Apache Jackrabbit Oak)
OSGi (Apache Felix)
Den allmänna regeln är att föredra API:erna/abstraktionerna i följande ordning:
Om ett API tillhandahålls av AEM föredrar du det framför Sling, JCR och OSGi. Om AEM inte har något API bör du Sling över JCR och OSGi.
Den här ordningen är en allmän regel, vilket innebär undantag. Godtagbara orsaker att bryta mot den här regeln är:
Välkända undantag, enligt beskrivningen nedan.
Nödvändiga funktioner är inte tillgängliga i ett API på högre nivå.
Fungerar med befintlig kod (anpassad eller AEM produktkod) som i sin tur använder ett mindre prioriterat API, och kostnaden för att gå över till det nya API:t är obefogad.
AEM API:er innehåller abstraktioner och funktioner som är specifika för produkterade användningsfall.
AEM PageManager och Sida API:er innehåller abstraktioner för cq:Page
noder i AEM som representerar webbsidor.
Dessa noder är tillgängliga via Sling API:er som resurser och JCR-API:er som noder, AEM API:er innehåller abstraktioner för vanliga användningsområden. Genom att använda AEM API:er kan du säkerställa ett konsekvent beteende mellan AEM och anpassningar och tillägg till AEM.
AEM-API:er har en paketintern inställning som identifieras av följande Java™-paket, i prioritetsordning:
com.adobe.cq
com.adobe.granite
com.day.cq
The com.adobe.cq
paketet har stöd för produktanvändning. com.adobe.granite
har stöd för användning på olika plattformar, t.ex. arbetsflöden eller uppgifter (som används i olika produkter: AEM Assets, Sites osv.).
The com.day.cq
paketet innehåller "original"-API:er. Dessa API:er åtgärdar viktiga abstraktioner och funktioner som fanns före och/eller runt Adobe förvärv av Day CQ. Dessa API:er stöds och bör undvikas om inte com.adobe.cq
eller com.adobe.granite
paket har INTE ett (nyare) alternativ.
Nya abstraktioner som Content Fragments och Experience Fragments är inbyggd i com.adobe.cq
blanksteg i stället för com.day.cq
beskrivs nedan.
AEM stöder flera frågespråk. De tre huvudspråken är JCR-SQL2, XPath och AEM Query Builder.
Det viktigaste problemet är att ha ett konsekvent frågespråk i hela kodbasen, vilket minskar komplexiteten och gör att du lättare kan förstå kostnaderna.
Alla frågespråk har i princip samma prestandaprofiler som Apache Oak överför dem till JCR-SQL2 för slutlig frågekörning, och konverteringstiden till JCR-SQL2 är försumbar jämfört med själva frågetiden.
Rekommenderat API är AEM Query Builder, som är den högsta nivån för abstraktion och ger ett robust API för att skapa, köra och hämta resultat för frågor, och som ger följande:
Enkel, parametriserad frågekonstruktion (frågeparametrar som modelleras som en karta)
Inbyggt Java™ API och HTTP API:er
AEM predikat stöder gemensamma frågekrav
Utbyggbart API, som möjliggör utveckling av anpassat frågepredikat
JCR-SQL2 och XPath kan köras direkt via Sling och JCR-API:erreturnerar resultaten Sling Resurs eller JCR-noder, respektive
AEM QueryBuilder API läcker ett ResourceResolver-objekt. Följ detta för att minska läckan kodexempel.
Apache Sling är RESTful-webbramverket som stöder AEM. Sling tillhandahåller routning av HTTP-begäran, modeller av JCR-noder som resurser, ger säkerhetskontext och mycket annat.
Sling API:er har dessutom fördelen att byggas för tillägg, vilket innebär att det ofta är enklare och säkrare att förstärka beteendet i applikationer som byggts med Sling API:er än de mindre utökningsbara JCR-API:erna.
Åtkomst till JCR-noder som Sling Resources och få tillgång till deras data via ValueMaps.
Tillhandahålla säkerhetskontext via ResursResolver.
Skapa och ta bort resurser via ResourceResolver skapa/flytta/kopiera/ta bort metoder.
Uppdatera egenskaper via ModiitableValueMap.
Byggstenar för bearbetning av begäranden
Byggstenar för asynkron bearbetning
The JCR (Java™ Content Repository) 2.0 API:er ingår i en specifikation för JCR-implementeringar (i AEM fall, Apache Jackrabbit Oak). All JCR-implementering måste följa och implementera dessa API:er, och är därför den lägsta nivån för API för interaktion med AEM.
Själva JCR är en hierarkisk/trädbaserad NoSQL-AEM som används som innehållsdatabas. JCR har en mängd API:er som stöds, från innehålls-CRUD till frågor om innehåll. Trots detta robusta API är det sällan de föredras framför de AEM och Sling abstraktioner.
Använd alltid JCR-API:erna framför API:erna för Apache Jackrabbit Oak. JCR-API:erna är för interagera med en JCR-databas, medan Oak API:er är för implementera en JCR-databas.
Även om JCR är AEM innehållsdatabas är dess API:er INTE den föredragna metoden för interaktion med innehållet. Använd i stället AEM API:er (Sida, Resurser, Tagg o.s.v.) eller Sling Resource API:er för att få bättre abstraktioner.
En stor användning av JCR-API:ernas Session- och Node-gränssnitt i ett AEM program är kodlukt. Säkerställ Sling API:er bör användas i stället.
JCR-observation (lyssnar efter JCR-händelser)
Skapa djupnodsstrukturer
Det finns liten överlappning mellan OSGi-API:erna och API:erna på den högre nivån (AEM, Sling, och JCR) och behovet av att använda API:er för OSGi är sällsynt och kräver stor AEM utvecklingskompetens.
OSGi definierar en specifikation som alla OSGi-behållare måste implementera och följa. AEM OSGi-implementering, Apache Felix, innehåller också flera egna API:er.
org.osgi
) över API:er för Apache Felix (org.apache.felix
).OSGi-anteckningar för att deklarera OSGi-tjänster och -komponenter.
OSGi-API:er för dynamiskt kodning Kör/registrera OSGi-tjänster/komponenter.
Följande är vanliga undantag till reglerna som definieras ovan.
När det gäller OSGi-abstraktioner på låg nivå, som att definiera eller läsa i OSGi-komponentegenskaper, finns de nyare abstreringarna i org.osgi
är att föredra framför Sling-abstraktioner på högre nivå. De konkurrerande Sling-abstraktionerna har inte markerats som @Deprecated
och föreslå org.osgi
alternativ.
Observera även att noddefinitionen för OSGi-konfigurationen föredrar cfg.json
över sling:OsgiConfig
format.
Föredra com.day.cq.dam.api
över com.adobe.granite.asset.api
.
com.day.cq
Med Assets API:er får du mer kostnadsfria verktyg för att AEM användningsfall för resurshantering.@SlingServlet
@SlingFilter
Nedan följer några praktiska Java™-kodfragment som illustrerar de effektivaste strategierna för vanliga användningsområden med hjälp av beskrivna API:er. De här fragmenten visar också hur du går från mindre prioriterade API:er till mer önskade API:er.
Sedan AEM 6.2 har Sling ResourceResolver är AutoClosable
i en try-with-resources -programsats. Med den här syntaxen anropas resourceResolver .close()
behövs inte.
@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) { .. }
ResourceResolvers kan bara stängas manuellt i en finally
om tekniken för automatisk stängning som visas ovan inte kan användas.
@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(); }
}
Resource resource = ResourceResolver.getResource("/path/to/the/resource");
Resource resource = resourceResolver.getResource(node.getPath());
The DamUtil.resolveToAsset(..)
funktionen löser alla resurser under dam:Asset
till objektet Asset genom att gå upp i trädet efter behov.
Asset asset = DamUtil.resolveToAsset(resource);
Att anpassa en resurs till en resurs kräver att själva resursen är dam:Asset
nod.
Asset asset = resource.adaptTo(Asset.class);
pageManager.getContainingPage(..)
löser alla resurser under cq:Page
till objektet Page genom att gå upp i trädet efter behov.
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page page = pageManager.getContainingPage(resource);
Page page2 = pageManager.getContainingPage("/content/path/to/page/jcr:content/or/component");
Att anpassa en resurs till en sida kräver att själva resursen är cq:Page
nod.
Page page = resource.adaptTo(Page.class);
Använd Page-objektets get-metoder för att få välkända egenskaper (getTitle()
, getDescription()
och så vidare) och page.getProperties()
för att få [cq:Page]/jcr:content
ValueMap för att hämta andra egenskaper.
Page page = resource.adaptTo(Page.class);
String title = page.getTitle();
Calendar value = page.getProperties().get("cq:lastModified", Calendar.getInstance());
Resurs-API:t innehåller praktiska metoder för att läsa egenskaper från [dam:Asset]/jcr:content/metadata
nod. Detta är inte en ValueMap, den andra parametern (standardvärde och datatypsbyte) stöds inte.
Asset asset = resource.adaptTo(Asset.class);
String title = asset.getMetadataValue("dc:title");
Calendar lastModified = (Calendar) asset.getMetadata("cq:lastModified");
När egenskaper lagras på platser (egenskaper eller relativa resurser) där AEM-API:erna (Sida, Resurs) inte har direktåtkomst, Sling Resurser och ValueMaps kan användas för att hämta data.
ValueMap properties = resource.getValueMap();
String value = properties.get("jcr:title", "Default title");
String relativeResourceValue = properties.get("relative/propertyName", "Default value");
I det här fallet kan AEM-objektet behöva konverteras till Sling Resource för att effektivt hitta önskad egenskap eller underresurs.
Resource resource = page.adaptTo(Resource.class);
Resource resource = asset.adaptTo(Resource.class);
Använd Sling's ModiitableValueMap för att skriva egenskaper till noder. Detta kan bara skriva till den omedelbara noden (relativa egenskapssökvägar stöds inte).
Anteckna samtalet till .adaptTo(ModifiableValueMap.class)
kräver skrivbehörighet för resursen, annars returneras null.
ModifiableValueMap properties = resource.adaptTo(ModifiableValueMap.class);
properties.put("newPropertyName", "new value");
properties.put("propertyNameToUpdate", "updated value");
properties.remove("propertyToRemove");
resource.getResourceResolver().commit();
Använd alltid PageManager för att skapa sidor när en sidmall används, vilket krävs för att definiera och initiera sidor i 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(); }
ResourceResolver har stöd för grundläggande åtgärder för att skapa resurser. När du skapar abstraktioner på högre nivå (AEM sidor, resurser, taggar och så vidare) använder du de metoder som deras respektive hanterare tillhandahåller.
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();
ResourceResolver stöder borttagning av en resurs. När du skapar abstraktioner på högre nivå (AEM sidor, resurser, taggar och så vidare) använder du de metoder som deras respektive hanterare tillhandahåller.
resourceResolver.delete(resource);
resourceResolver.commit();