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