AEM Querybuilder获得引用

时间:2019-07-11 14:43:53

标签: aem aem-6

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

我无法弄清的一件事是如何确定资产或页面是否被另一页面引用。我关心的主要问题是是否引用了简单的true / false。理想情况下,我希望可以在初始查询中使用它,而不必对每个资产进行查询,但是如果那是唯一的方法,那么我认为理论上可以接受。

我现在可以运行一个示例查询来获取有关资产的一些信息(我将示例的结果限制为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。

谢谢!

2 个答案:

答案 0 :(得分:0)

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

我希望这会有所帮助。祝您编码愉快!

答案 1 :(得分:0)

有一个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。