【问题标题】:AEM Querybuilder Getting If ReferencedAEM Querybuilder 被引用时获取
【发布时间】:2019-07-11 14:43:53
【问题描述】:

我帮助监督(质量保证)AEM 上的一个网站,该网站拥有大约 65,000 个页面、320,000 项资产和大约 300 名可以发布和进行更改的用户。非常有用的一件事是一位前 IT 员工为我们编写的脚本,该脚本使用 querybuilder servlet 进行查询并提取页面和资产的完整列表。我已经能够获取此输出并使用它构建各种自动报告。

我无法弄清楚的一件事是如何找出资产或页面是否被另一个页面引用。我关心的主要事情只是一个简单的真/假是否被引用。理想情况下,我希望它可以在初始查询中,并且不必对每个单独的资产进行查询,但如果这是唯一的方法,那么我猜理论上它是可以接受的。

我目前可以运行一个示例查询以获取有关资产的一些信息(我将此示例限制为 5 个结果):

http://localhost:4502/bin/querybuilder.json?p.hits=selective&p.offset=0&p.limit=5&p.properties=jcr%3acontent%2fmetadata%2fdc%3aformat%20jcr%3acontent%2fmetadata%2fdc%3atitle%20jcr%3apath%20&path=%2fcontent%2fdam&type=dam%3aAsset

如果被引用,有什么方法可以添加到该字段?还是所有对它的引用的数组?

我们目前正在运行 AEM 6.2,但很快将升级到 6.4。

谢谢!

【问题讨论】:

    标签: aem aem-6


    【解决方案1】:

    根据您的要求,您可以利用AssetReferenceSearch API,它可以提供页面中使用的资产的详细信息(cq:Page 类型的节点)。

    您可以使用以下代码来完成您的任务 -

    package org.redquark.aem.assets.core;
    
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    
    import javax.jcr.Node;
    import javax.servlet.Servlet;
    
    import org.apache.sling.api.SlingHttpServletRequest;
    import org.apache.sling.api.SlingHttpServletResponse;
    import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
    import org.osgi.service.component.annotations.Component;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.day.cq.dam.api.Asset;
    import com.day.cq.dam.commons.util.AssetReferenceSearch;
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    
    /**
     * @author Anirudh Sharma
     *
     */
    @Component(
            service = Servlet.class, 
            property = { 
                    "sling.servlet.methods=GET", 
                    "sling.servlet.resourceTypes=cq/Page",
                    "sling.servlet.selectors=assetreferences", 
                    "sling.servlet.extensions=json", 
                    "service.ranking=1000" 
                    }
            )
    public class FindReferencedAssetsServlet extends SlingSafeMethodsServlet {
    
        // Generated serial version UID
        private static final long serialVersionUID = 8446564170082865006L;
    
        private final Logger log = LoggerFactory.getLogger(this.getClass());
    
        private static final String DAM_ROOT = "/content/dam";
    
        @Override
        protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
    
            response.setContentType("application/json");
    
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
    
            try {
    
                // Get the current node reference from the resource object
                Node currentNode = request.getResource().adaptTo(Node.class);
    
                if (currentNode == null) {
                    // Every adaptTo() can return null, so let's handle the case here
                    // However, it is very unlikely
                    log.error("Cannot adapt resource {} to a node", request.getResource().getPath());
                    response.getOutputStream().print(new Gson().toString());
    
                    return;
                }
    
                // Using AssetReferenceSearch which will do all the work for us
                AssetReferenceSearch assetReferenceSearch = new AssetReferenceSearch(currentNode, DAM_ROOT,
                        request.getResourceResolver());
    
                Map<String, Asset> result = assetReferenceSearch.search();
    
                List<AssetDetails> assetList = new LinkedList<>();
    
                for (String key : result.keySet()) {
    
                    Asset asset = result.get(key);
    
                    AssetDetails assetDetails = new AssetDetails(asset.getName(), asset.getPath(), asset.getMimeType());
    
                    assetList.add(assetDetails);
                }
    
                String jsonOutput = gson.toJson(assetList);
    
                response.getOutputStream().println(jsonOutput);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
    
        }
    }
    

    对应的AssetDetails模型类如下——

    package org.redquark.aem.assets.core;
    
    /**
     * @author Anirudh Sharma
     */
    public class AssetDetails {
    
        private String name;
        private String path;
        private String mimeType;
    
        /**
         * @param name
         * @param path
         * @param mimeType
         */
        public AssetDetails(String name, String path, String mimeType) {
            this.name = name;
            this.path = path;
            this.mimeType = mimeType;
        }
    
        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
    
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
    
        /**
         * @return the path
         */
        public String getPath() {
            return path;
        }
    
        /**
         * @param path the path to set
         */
        public void setPath(String path) {
            this.path = path;
        }
    
        /**
         * @return the mimeType
         */
        public String getMimeType() {
            return mimeType;
        }
    
        /**
         * @param mimeType the mimeType to set
         */
        public void setMimeType(String mimeType) {
            this.mimeType = mimeType;
        }
    }
    

    现在,您可以通过以下请求调用此 servlet -

    http://localhost:4502/content/we-retail/language-masters/en/men.assetreferences.json.

    这将给出以下格式的输出

    [
      {
        "name": "running-trail-man.jpg",
        "path": "/content/dam/we-retail/en/activities/running/running-trail-man.jpg",
        "mimeType": "image/jpeg"
      },
      {
        "name": "enduro-trail-jump.jpg",
        "path": "/content/dam/we-retail/en/activities/biking/enduro-trail-jump.jpg",
        "mimeType": "image/jpeg"
      },
      {
        "name": "indoor-practicing.jpg",
        "path": "/content/dam/we-retail/en/activities/climbing/indoor-practicing.jpg",
        "mimeType": "image/jpeg"
      }
    ]
    

    您可以根据需要编辑 AssetDetails 类。

    我希望这会有所帮助。快乐编码!!!

    【讨论】:

      【解决方案2】:

      有一个 OOTB servlet 将返回引用特定页面或资产的页面列表

      要检查是否引用了页面或资产,请使用

      https://localhost:4502/bin/wcm/references?
      _charset_=utf-8
      &path=<path of the page>
      &predicate=wcmcontent
      &exact=false
      

      输出将是一个 json 响应,其中包含一个名为“pages”的引用数组。如果页面没有被引用,它将是一个空数组。

      这个 servlet 使用其他答案提到的 ReferenceSearch API。如果您需要此值作为 AEM 之外的 JSON,您可以直接使用 OOTB,而无需编写自己的 servlet。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-13
        相关资源
        最近更新 更多