Java API 우수 사례

AEM(Adobe Experience Manager)은 개발 중에 사용할 많은 Java API를 표시하는 풍부한 오픈 소스 소프트웨어 스택에 빌드되어 있습니다. 이 문서에서는 주요 API와 그 사용 시기 및 이유를 설명합니다.

AEM은 4개의 기본 Java API 세트를 기반으로 구축됩니다.

  • AEM(Adobe Experience Manager)

    • 페이지, 자산, 워크플로우 등과 같은 제품 추상
  • Apache Sling Web Framework

    • 리소스, 값 맵 및 HTTP 요청과 같은 REST 및 리소스 기반 추상화.
  • JCR(Apache Jackrabbit Oak)

    • 노드, 속성 및 세션과 같은 데이터 및 컨텐츠 추상.
  • OSGi(Apache Felix)

    • 서비스 및 (OSGi) 구성 요소와 같은 OSGi 애플리케이션 컨테이너 추상.

Java API 기본 설정 "경험 규칙"

일반적인 규칙은 API/추상을 다음 순서로 선호합니다.

  1. AEM
  2. 슬링
  3. JCR
  4. OSGi

API가 AEM에서 제공하는 경우 보다 선호합니다 Sling, JCR 및 OSGi. AEM에서 API를 제공하지 않는 경우 를 선호합니다 Sling JCR과 OSGi를 통해 지원됩니다.

이 순서는 일반적인 규칙이며, 이것은 예외가 있음을 의미합니다. 이 규칙에서 벗어나는 허용되는 이유는 다음과 같습니다.

  • 잘 알려진 예외 사항입니다.

  • 더 높은 수준의 API에서는 필수 기능을 사용할 수 없습니다.

  • 기존 코드(사용자 지정 또는 AEM 제품 코드)의 컨텍스트에서 작동하며, 이 코드 자체는 덜 선호하는 API를 사용하며, 새 API로 이동하는 비용은 적절하지 않습니다.

    • 혼합을 만드는 것보다 낮은 수준의 API를 일관되게 사용하는 것이 좋습니다.

AEM API

AEM API는 생산화된 사용 사례와 관련된 추상화와 기능을 제공합니다.

예: AEM PageManager페이지 API는 cq:Page 웹 페이지를 나타내는 AEM의 노드입니다.

이러한 노드는 Sling API는 리소스로, JCR API는 노드로, AEM API는 일반적인 사용 사례에 대한 추상을 제공합니다. AEM API를 사용하면 AEM 제품, 사용자 지정 및 AEM 확장 간에 일관된 동작을 보장합니다.

com.adobe.* vs com.day.* API

AEM API에는 기본 설정 순서로 다음 Java 패키지로 식별되는 인트라 패키지 기본 설정이 있습니다.

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

com.adobe.cq 는 제품 사용 사례를 지원합니다. com.adobe.granite 은 워크플로우 또는 작업(제품 간에 사용)과 같은 제품 간 플랫폼 사용 사례를 지원합니다. AEM Assets, Sites 등).

com.day.cq 에는 "원래" API가 포함되어 있습니다. 이러한 API는 Adobe의 고객 확보 전 및/또는 그 주변에 존재했던 핵심 추상 및 기능을 해결합니다 Day CQ. 이러한 API는 지원되지 않으므로 com.adobe.cq 또는 com.adobe.granite (최신) 대체 요소를 제공합니다.

다음과 같은 새로운 추상 Content Fragments 및 Experience Fragments 기본적으로 com.adobe.cq 공간 대신 com.day.cq 아래에 설명되어 있습니다.

쿼리 API

AEM에서는 여러 쿼리 언어를 지원합니다. 3개의 주요 언어는 다음과 같습니다 JCR-SQL2, XPath 및 AEM Query Builder.

가장 중요한 문제는 코드 베이스에서 일관된 쿼리 언어를 유지하는 것이며, 이를 통해 복잡성을 줄이고 비용을 절감할 수 있습니다.

모든 쿼리 언어에는 Apache Oak 최종 쿼리 실행을 위해 JCR-SQL2에 트랜스더링하며 JCR-SQL2로의 변환 시간은 쿼리 시간 자체에 비해 거의 무시할 수 있습니다.

기본 API는 다음과 같습니다 AEM Query Builder- 가장 높은 수준의 추상화이며 쿼리에 대한 결과를 구성, 실행 및 검색하기 위한 강력한 API를 제공하며 다음을 제공합니다.

주의

AEM QueryBuilder API에서 ResourceResolver 개체가 누출됩니다. 이 누수를 완화하려면 다음 단계를 수행하십시오 코드 샘플.

Sling API

Apache Sling 는 AEM의 기반이 되는 RESTful 웹 프레임워크입니다. Sling 에서는 HTTP 요청 라우팅, JCR 노드를 리소스로 모델, 보안 컨텍스트 등을 제공합니다.

Sling API는 확장을 위해 빌드되므로 이를 사용하여 빌드된 애플리케이션의 동작을 보다 쉽고 안전하게 늘릴 수 있습니다 Sling 확장 가능한 JCR API보다 큰 API.

의 일반적인 사용 Sling API

JCR API

다음 JCR(Java Content Repository) 2.0 API 는 JCR 구현에 대한 사양의 일부입니다(AEM의 경우). Apache Jackrabbit Oak). 모든 JCR 구현은 이러한 API를 준수하고 구현해야 하므로 AEM 콘텐츠과 상호 작용하기 위한 가장 낮은 수준의 API입니다.

JCR 자체는 컨텐츠 저장소로 사용하는 계층적/트리 기반 NoSQL 데이터 저장소 AEM입니다. JCR에는 컨텐츠 CRUD부터 콘텐츠 쿼리 등 다양한 지원되는 API의 범위가 있습니다. 이러한 강력한 API에도 불구하고 높은 수준의 AEM보다 선호되는 경우는 거의 없습니다. Sling 추상.

Apache Jackrabbit Oak API보다 항상 JCR API를 선호합니다. JCR API는 다음 용입니다 상호 작용 JCR 저장소를 사용하는 반면 Oak API는 을 위한 것입니다 구현 JCR 저장소.

JCR API에 대한 일반적인 오해

JCR은 AEM 컨텐츠 저장소이지만 API는 컨텐츠와 상호 작용하기 위해 선호되는 방법이 아닙니다. 대신 AEM API(페이지, 자산, 태그 등)를 선호합니다. 또는 Sling 리소스 API에서 더 나은 추상을 제공하므로

주의

AEM 애플리케이션에서 JCR API의 세션 및 노드 인터페이스를 광범위하게 사용하는 것은 코드 냄새입니다. 확인 Sling API를 대신 사용하면 안 됩니다.

JCR API의 일반적인 사용

OSGi API

OSGi API와 상위 수준 API(AEM, Sling, 및 JCR) 및 OSGi API를 사용해야 하는 경우가 드물며 AEM 개발에 대한 높은 수준의 전문 지식이 필요합니다.

OSGi와 Apache Felix API

OSGi는 모든 OSGi 컨테이너가 구현하고 준수해야 하는 사양을 정의합니다. AEM OSGi 구현인 Apache Felix는 자체 API 몇 가지를 제공합니다.

  • OSGi API 선호(org.osgi)을 Apache Felix API에 대해 지원합니다(org.apache.felix).

OSGi API의 일반적인 사용

규칙에 대한 예외

다음은 위에 정의된 규칙에 대한 일반적인 예외입니다.

OSGi API

OSGi 구성 요소 속성에서 정의하거나 읽는 등의 저수준 OSGi 추상을 처리할 때 다음과 같이 제공되는 새로운 추상 org.osgi 상위 수준 Sling 작업보다 선호됩니다. 경쟁 Sling 추상화가 @Deprecated 그리고 추천합니다 org.osgi 대체.

또한 OSGi 구성 노드 정의가 더 선호됩니다 cfg.json 오버 sling:OsgiConfig 형식 지정

AEM Asset API

  • 기본 설정 com.day.cq.dam.api over com.adobe.granite.asset.api.

    • 반면에 com.day.cq Assets API는 AEM 자산 관리 사용 사례에 더 많은 무료 도구를 제공합니다.
    • Granite Assets API는 낮은 수준의 자산 관리 사용 사례(버전, 관계)를 지원합니다.

쿼리 API

  • AEM QueryBuilder는 추천, 맞춤법 검사 및 색인 힌트 등의 기타 일반적인 함수 간에 있을 수 있습니다. 이러한 함수를 사용하여 쿼리하려면 JCR-SQL2가 선호됩니다.

Sling 서블릿 등록

Sling 필터 등록

유용한 코드 조각

다음은 설명된 API를 사용하는 일반적인 사용 사례에 대한 우수 사례를 보여주는 유용한 Java 코드 조각입니다. 이러한 코드 조각은 더 낮은 기본 API에서 더 선호하는 API로 이동하는 방법을 보여 줍니다.

JCR 세션 Sling ResourceResolver

Sling ResourceResolver 자동 닫기

AEM 6.2 이후, Sling ResourceResolver가 AutoClosable 에서 리소스 사용 문. 이 구문을 사용하는에 대한 명시적 호출입니다 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) { .. }

Sling ResourceResolver를 수동으로 닫았습니다.

ResourceResolver는 finally 블록 위에 표시된 자동 닫기 기술을 사용할 수 없는 경우

@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 경로 Sling Resource

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

JCR 노드 대상 Sling Resource

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

Sling Resource AEM Asset

권장 방법

DamUtil.resolveToAsset(..)에서 모든 리소스를 확인합니다. dam:Asset 필요에 따라 트리 위로 이동하여 Asset 개체에 추가합니다.

Asset asset = DamUtil.resolveToAsset(resource);

대체 방법

자산을 자산에 적응하려면 리소스 자체가 dam:Asset 노드 아래에 있어야 합니다.

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

Sling AEM에 리소스 페이지

권장 방법

pageManager.getContainingPage(..) 에서 모든 리소스를 확인합니다. cq:Page 필요에 따라 트리 위로 이동하여 Page 개체에 추가합니다.

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

대체 방법

리소스를 페이지에 적용하려면 리소스 자체가 cq:Page 노드 아래에 있어야 합니다.

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

AEM 페이지 속성 읽기

Page 개체의 getter를 사용하여 잘 알려진 속성(getTitle(), getDescription()등) 및 page.getProperties() 얻다 [cq:Page]/jcr:content 다른 속성을 검색하기 위한 ValueMap입니다.

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

AEM 자산 메타데이터 속성 읽기

Asset API는 [dam:Asset]/jcr:content/metadata 노드 아래에 있어야 합니다. 이 매개 변수는 ValueMap이 아니며, 두 번째 매개 변수(기본값 및 자동 유형 캐스팅이 지원되지 않습니다.

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

읽기 Sling Resource 속성

속성이 AEM API(페이지, 자산)에서 직접 액세스할 수 없는 위치(속성 또는 상대 리소스)에 저장되는 경우, Sling 리소스 및 ValueMap을 사용하여 데이터를 가져올 수 있습니다.

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

이 경우 AEM 개체를 Sling Resource 를 사용하여 원하는 속성 또는 하위 리소스를 효율적으로 찾을 수 있습니다.

AEM 페이지 대상 Sling Resource

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

AEM Asset 대상 Sling Resource

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

속성을 사용하여 쓰기 Sling의 수정 가능한 값 맵

사용 Slings 수정 가능한 값 맵 노드에 속성을 씁니다. 직접 노드에만 쓸 수 있습니다(상대 속성 경로는 지원되지 않음).

에 대한 호출을 확인합니다. .adaptTo(ModifiableValueMap.class) 리소스에 대한 쓰기 권한이 필요합니다. 그렇지 않으면 null이 반환됩니다.

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

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

resource.getResourceResolver().commit();

AEM 페이지 만들기

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

만들기 Sling 리소스

ResourceResolver는 리소스를 만드는 기본 작업을 지원합니다. 더 높은 수준의 추상을 만드는 경우(AEM 페이지, 자산, 태그 등) 각 관리자가 제공하는 방법을 사용합니다.

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

삭제 Sling 리소스

ResourceResolver에서 리소스 제거를 지원합니다. 더 높은 수준의 추상을 만들 때(AEM 페이지, 자산, 태그 등) 각 관리자가 제공하는 방법을 사용합니다.

resourceResolver.delete(resource);

resourceResolver.commit();

이 페이지에서는