首页 > 解决方案 > AEM Querybuilder 获取(如果引用)

问题描述

我帮助监督(质量保证)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。

谢谢!

标签: aemaem-6

解决方案


根据您的要求,您可以利用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 类。

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


推荐阅读