AEM 6.5日志报错无HTML渲染器,如何用Servlet删除无sling:resourceType节点
解决AEM 6.5中批量删除缺少
sling:resourceType属性节点的Servlet实现方案 问题背景
在AEM 6.5环境中,已为DefaultGetServlet勾选Enable JSON和Enable XML选项,但大量内容页面出现如下错误日志:
GET /content/test/.html HTTP/1.1]org.apache.sling.servlets.get.impl.DefaultGetServlet No renderer for extension html, cannot render resource JcrNodeResource, type=nt:unstructured, superType=null, path=/content//jcr:content/root/responsivegrid/_copy.
经调试确认,问题根源是相关节点缺失sling:resourceType属性,且项目中存在大量此类节点,需通过Servlet批量删除符合条件的节点(例如/content/company/us/en/test/text这类缺失属性的节点)。
Servlet实现步骤
1. 核心逻辑说明
通过Servlet遍历指定路径下的节点,筛选出类型为nt:unstructured且不存在sling:resourceType属性的节点执行删除操作。需注意权限控制、事务处理,同时避免一次性遍历过大节点树以优化性能。
2. 代码实现
import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.servlets.HttpConstants; import org.apache.sling.api.servlets.SlingSafeMethodsServlet; import org.osgi.framework.Constants; import org.osgi.service.component.annotations.Component; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.servlet.Servlet; import java.io.IOException; @Component( service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "=Servlet to delete nodes missing sling:resourceType", "sling.servlet.methods=" + HttpConstants.METHOD_GET, "sling.servlet.paths=" + "/bin/deleteMissingResourceTypeNodes" } ) public class DeleteMissingResourceTypeServlet extends SlingSafeMethodsServlet { @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { ResourceResolver resolver = request.getResourceResolver(); // 可通过请求参数传入目标根路径,默认示例路径为/content/company/us/en/test String rootPath = request.getParameter("rootPath") != null ? request.getParameter("rootPath") : "/content/company/us/en/test"; Resource rootResource = resolver.getResource(rootPath); if (rootResource == null) { response.getWriter().write("Root path not found: " + rootPath); return; } try { Session session = resolver.adaptTo(Session.class); traverseAndDeleteNodes(rootResource.adaptTo(Node.class), response); session.save(); response.getWriter().write("Nodes deletion completed successfully"); } catch (RepositoryException e) { response.getWriter().write("Error deleting nodes: " + e.getMessage()); e.printStackTrace(); } } private void traverseAndDeleteNodes(Node node, SlingHttpServletResponse response) throws RepositoryException, IOException { // 检查当前节点是否符合删除条件:nt:unstructured类型且无sling:resourceType属性 if ("nt:unstructured".equals(node.getPrimaryNodeType().getName()) && !node.hasProperty("sling:resourceType")) { String nodePath = node.getPath(); node.remove(); response.getWriter().write("Deleted node: " + nodePath + "\n"); return; } // 递归遍历子节点 Node childNode = node.getNodes().nextNode(); while (childNode != null) { String childPath = childNode.getPath(); try { traverseAndDeleteNodes(childNode, response); } catch (RepositoryException e) { response.getWriter().write("Error processing node " + childPath + ": " + e.getMessage() + "\n"); } childNode = node.getNodes().nextNode(); } } }
3. 使用说明
- 编译打包后将该Servlet部署到AEM实例
- 访问
http://<your-aem-host>:<port>/bin/deleteMissingResourceTypeNodes?rootPath=/content/company/us/en/test触发删除操作,rootPath参数可自定义要扫描的根路径 - 重要提醒:操作前务必做好内容备份,建议先在测试环境验证逻辑,避免误删有效节点
4. 权限配置
需确保Servlet关联的服务用户具备内容节点的删除权限,可通过AEM用户权限配置界面,为该用户添加jcr:removeNode等必要权限。
内容的提问来源于stack exchange,提问作者Vijitha
相关产品推荐
相关产品推荐

