DokumentationAEMSjälvstudiekurser om AEMSjälvstudiekurser om AEM Foundation

Java™ API Best Practices

Senast uppdaterad: 5 maj 2025
  • Gäller:
  • Experience Manager 6.4
  • Experience Manager 6.5
  • Ämnen:
  • API:er

Skapat för:

  • Nybörjare
  • Utvecklare

Adobe Experience Manager (AEM) bygger på en kraftfull 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)

    • Produktabstraktioner som sidor, resurser, arbetsflöden osv.
  • Apache Sling Web Framework

    • REST och resursbaserade abstraktioner som resurser, värdescheman och HTTP-begäranden.
  • JCR (Apache Jackrabbit Oak)

    • Data- och innehållsabstraktioner som nod, egenskaper och sessioner.
  • OSGi (Apache Felix)

    • OSSGi-programbehållarabstraktioner som tjänster och OSGi-komponenter.

Java™ API-inställning för"tumregel"

Den allmänna regeln är att föredra API:erna/abstraktionerna i följande ordning:

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

Om ett API tillhandahålls av AEM bör du föredra det framför Sling, JCR och OSGi. Om AEM inte har något API bör du föredra Sling framför 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 produktkod 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.

    • Det är bättre att konsekvent använda API:t på lägre nivå än att skapa en blandning.

AEM API:er

  • AEM API JavaDocs

AEM API:er innehåller abstraktioner och funktioner som är specifika för produktioner.

AEM-API:erna PageManager och Page innehåller till exempel 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, men AEM API:er innehåller abstraktioner för vanliga användningsområden. Med AEM API:er säkerställs ett konsekvent beteende mellan AEM och AEM samt anpassningar och tillägg.

com.adobe.* vs com.day.* API:er

AEM-API:er har en paketspecifik inställning som identifieras av följande Java™-paket, i prioritetsordning:

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

Paketet com.adobe.cq har stöd för produktanvändningsfall, medan com.adobe.granite har stöd för flerproduktsplattformsanvändning, som arbetsflöde eller uppgifter (som används för olika produkter: AEM Assets, Sites, osv.).

Paketet com.day.cq innehåller ursprungliga 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, såvida inte com.adobe.cq- eller com.adobe.granite-paketen inte har ett (nyare) alternativ.

Nya abstraktioner som Content Fragments och Experience Fragments är inbyggda i com.adobe.cq-utrymmet i stället för com.day.cq som beskrivs nedan.

Fråga API:er

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, eftersom Apache Oak kopplar 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.

Det önskade API:t är AEM Query Builder, som är den högsta nivån för abstraktion och som tillhandahåller 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 Query Debugger

  • AEM förutsäger som stöder gemensamma frågekrav

  • Utbyggbart API, som möjliggör utveckling av anpassade frågepredikat

  • JCR-SQL2 och XPath kan köras direkt via Sling och JCR API:er, vilket returnerar resultatet Sling Resources respektive JCR Nodes.

CAUTION
AEM QueryBuilder API läcker ett ResourceResolver-objekt. Följ det här kodexemplet om du vill minska läckan.

Sling API:er

  • Apache Sling API JavaDocs

Apache Sling är det RESTful-webbramverk 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 skapas för tillägg, vilket innebär att det ofta är enklare och säkrare att förstärka beteendet för program som skapats med Sling API:er än de mindre utökningsbara JCR-API:erna.

Vanliga användningsområden för Sling API:er

  • Åtkomst till JCR-noder som Sling Resources och åtkomst till deras data via ValueMaps.

  • Tillhandahåller säkerhetskontext via ResourceResolver.

  • Skapar och tar bort resurser via ResourceResolver create/move/copy/delete-metoder.

  • Uppdaterar egenskaper via ModiitableValueMap.

  • Byggstenar för bearbetning av begäranden

    • Servlets
    • Serverfilter
  • Byggstenar för asynkron bearbetning

    • Händelse- och jobbhanterare
    • Schemaläggaren
    • Sling Models
  • Tjänstanvändare

JCR-API:er

  • JCR 2.0 JavaDocs

JCR-API:erna (Java™ Content Repository) 2.0 är en del av en specifikation för JCR-implementeringar (för AEM 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-innehåll.

Själva JCR är ett hierarkiskt/trädbaserat NoSQL-datalager som AEM använder 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ällsynt att de föredras framför AEM- och Sling-abstraktioner på högre nivå.

Använd alltid JCR-API:erna framför API:erna i Apache Jackrabbit Oak. JCR-API:erna är till för interaktion med en JCR-databas, medan Oak-API:erna är till för implementering av en JCR-databas.

Vanliga missuppfattningar om JCR-API:er

Även om JCR är AEM innehållsdatabas är dess API:er INTE den metod som rekommenderas för interaktion med innehållet. Använd i stället AEM API:er (Page, Assets, Tag o.s.v.) eller Sling Resource API:er så att de ger bättre abstraktioner.

CAUTION
En stor användning av JCR-API:ernas Session- och Node-gränssnitt i ett AEM-program är kodlukt. Se till att Sling API:er används i stället.

Vanliga användningsområden för JCR-API:er

  • Hantering av åtkomstkontroll

  • Auktoriserbar hantering (användare/grupper)

  • JCR-observation (lyssnar efter JCR-händelser)

  • Skapa djupnodsstrukturer

    • Även om Sling-API:erna har stöd för att skapa resurser, har JCR-API:erna bekväma metoder i JcrUtils och JcrUtil som gör det lättare att skapa djupstrukturer.

OSGi API:er

  • OSGi R6 JavaDocs
  • OSGi Declarative Services 1.2 Component Annotations JavaDocs
  • OSGi Declarative Services 1.2 Metatype Annotations JavaDocs
  • OSGi Framework JavaDocs

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 OSGi-API:er är sällsynt och kräver en hög nivå av AEM utvecklingsexpertis.

API:er för OSGi och Apache Felix

OSGi definierar en specifikation som alla OSGi-behållare måste implementera och följa. AEM OSGi-implementering, Apache Felix, har också ett antal egna API:er.

  • Föredra OSGi-API:er (org.osgi) framför Apache Felix-API:er (org.apache.felix).

Vanliga användningsområden för OSGi-API:er

  • OSGi-anteckningar för att deklarera OSGi-tjänster och -komponenter.

    • Föredra OSGi Declarative Services (DS) 1.2 Anteckningar över Felix SCR Annotations för deklaration av OSGi-tjänster och -komponenter
  • OSGi-API:er för dynamiskt inkodade Kör/registrera OSGi-tjänster/komponenter.

    • Föredra användningen av OSGi DS 1.2-anteckningar när villkorlig OSGi Service/Component Management inte behövs (vilket oftast är fallet).

Undantag för regeln

Följande är vanliga undantag till reglerna som definieras ovan.

OSGi API:er

När du hanterar OSGi-abstreringar på låg nivå, som att definiera eller läsa i OSGi-komponentegenskaper, föredras de nyare abstreringarna från org.osgi framför Sling-abstraktioner på högre nivå. Motsvarande Sling-abstractions har inte markerats som @Deprecated och föreslår alternativet org.osgi.

Observera också att noddefinitionen för OSGi-konfigurationen föredrar cfg.json framför formatet sling:OsgiConfig.

AEM Resurser-API:er

  • Föredra com.day.cq.dam.api över com.adobe.granite.asset.api.

    • Assets-API:n för com.day.cq erbjuder mer kostnadsfria verktyg för användning av AEM-resurser.
    • Granite Assets API:er har stöd för resurshanteringsfall på låg nivå (version, relationer).

Fråga API:er

  • AEM QueryBuilder stöder inte vissa frågefunktioner som förslag, stavningskontroll och indextips bland andra mindre vanliga funktioner. Du bör använda JCR-SQL2 för att fråga med dessa funktioner.

Sling servletregistrering

  • Sling serverregistrering, använd OSGi DS 1.2-anteckningar med @SlingServletResourceTypes istället för @SlingServlet

Sling Filterregistrering

  • Sling filterregistrering, använd OSGi DS 1.2-anteckningar med @SlingServletFilter framför @SlingFilter

Användbara kodfragment

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.

JCR-session till Sling ResourceResolver

Automatisk stängning av Sling ResourceResolver

Sedan AEM 6.2 är Sling ResourceResolver AutoClosable i en try-with-resources -sats. Med den här syntaxen behövs inget explicit anrop till resourceResolver .close().

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

Manuellt stängd Sling ResourceResolver

ResourceResolvers kan stängas manuellt i ett finally-block om det inte går att använda tekniken som visas ovan.

@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-sökväg till Sling Resource

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

JCR-nod till Sling Resource

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

Sling Resource till AEM Asset

Rekommenderad metod

Funktionen DamUtil.resolveToAsset(..) löser alla resurser under dam:Asset till objektet Asset genom att gå uppåt i trädet efter behov.

Asset asset = DamUtil.resolveToAsset(resource);

Alternativ metod

Om du anpassar en resurs till en resurs måste själva resursen vara noden dam:Asset.

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

Sling resurs till AEM-sida

Rekommenderad metod

pageManager.getContainingPage(..) löser alla resurser under cq:Page till sidobjektet genom att gå uppåt 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");

Alternativ metod

Om du anpassar en resurs till en sida måste själva resursen vara noden cq:Page.

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

Läs AEM Page-egenskaper

Använd Page-objektets get-metoder för att hämta välkända egenskaper (getTitle(), getDescription() o.s.v.) och page.getProperties() för att hämta [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());

Läs AEM Asset-metadataegenskaper

Resurs-API:t innehåller praktiska metoder för att läsa egenskaper från noden [dam:Asset]/jcr:content/metadata. 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");

Läs Sling Resource-egenskaper

När egenskaper lagras på platser (egenskaper eller relativa resurser) där AEM-API:erna (Sida, Tillgång) inte kan komma åt direkt, kan Sling-resurserna och ValueMaps 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.

AEM Page to Sling Resource

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

AEM-resurs till Sling Resource

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

Skriva egenskaper med ModiitableValueMap för Sling

Använd förfrån Sling för att skriva egenskaper till noder. Detta kan bara skriva till den omedelbara noden (relativa egenskapssökvägar stöds inte).

Observera att anropet 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();

Skapa en AEM-sida

Använd alltid PageManager för att skapa sidor när en sidmall används, vilket krävs för att du ska kunna 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(); }

Skapa en Sling-resurs

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 Pages, Assets, Tags osv.) 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();

Ta bort en Sling-resurs

ResourceResolver stöder borttagning av en resurs. När du skapar abstraktioner på högre nivå (AEM Pages, Assets, Tags osv.) använder du de metoder som deras respektive hanterare tillhandahåller.

resourceResolver.delete(resource);

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