Alfresco Java Web脚本获取文档属性运行报错问题排查求助
Alfresco Web脚本获取文档参数问题修复方案
现存问题汇总
- 1 模板渲染核心错误:你同时混用了
AbstractWebScript直接输出响应和FTL模板两种模式,且没有将数据对象放入模板渲染的模型中,导致FTL读取obj变量时为空,触发报错。 - 2 描述文件配置错误:
document-script.get.desc.xml中配置的URL、参数、默认返回格式均不符合需求,你需要的URL是/get-document-data,携带nodeRef和property参数,默认格式应为JSON而非HTML。 - 3 Java代码逻辑错误:
- 静态
JSONObject存在严重线程安全问题,多用户并发请求时数据会互相覆盖 - 错误调用
res.getEncodeResourceUrlFunction获取属性值,该方法是获取URL编码工具函数,和节点属性完全无关 - 未实现节点属性读取、子文件夹遍历的核心逻辑,没有注入Alfresco的
NodeService等核心服务
- 静态
- 4 FTL模板逻辑错误:你需求返回的是单个JSON对象而非数组,模板中错误使用
<#list>遍历非集合类型的obj,即使变量能正常读取也会报错。 - 5 Spring配置问题:如果使用模板驱动的Web脚本,应继承
DeclarativeWebScript而非AbstractWebScript,父Bean配置也对应调整。
修复方案
方案选择:采用声明式Web脚本(配合FTL模板,符合Alfresco最佳实践)
1 修复DocumentScript.java
import org.alfresco.model.ContentModel; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.DeclarativeWebScript; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptRequest; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class DocumentScript extends DeclarativeWebScript { // 注入Alfresco节点服务 private NodeService nodeService; @Override protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) { Map<String, Object> model = new HashMap<>(); // 获取请求参数 String nodeRefStr = req.getParameter("nodeRef"); String property = req.getParameter("property"); boolean includeChildren = Boolean.parseBoolean(req.getParameter("includeChildren")); // 参数校验 if (nodeRefStr == null || !NodeRef.isNodeRef(nodeRefStr)) { status.setCode(400, "无效的nodeRef参数"); return model; } NodeRef nodeRef = new NodeRef(nodeRefStr); // 读取指定属性值 Object propertyValue = nodeService.getProperty(nodeRef, QName.createQName(property)); model.put("nodeRef", nodeRefStr); model.put("value", propertyValue != null ? propertyValue.toString() : ""); // 支持返回子文件夹列表 if (includeChildren && nodeService.getType(nodeRef).equals(ContentModel.TYPE_FOLDER)) { List<Map<String, String>> children = new ArrayList<>(); nodeService.getChildAssocs(nodeRef).forEach(assoc -> { NodeRef childRef = assoc.getChildRef(); if (nodeService.getType(childRef).equals(ContentModel.TYPE_FOLDER)) { Map<String, String> child = new HashMap<>(); child.put("nodeRef", childRef.toString()); child.put("name", nodeService.getProperty(childRef, ContentModel.PROP_NAME).toString()); children.add(child); } }); model.put("children", children); } return model; } // Spring注入setter public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } }
2 修复document-script-context.xml
<bean id="webscript.alfresco.extension.get-document-data.get" class="alfresco.extension.templates.webscripts.repository.DocumentScript" parent="webscript"> <property name="nodeService" ref="NodeService"/> </bean>
3 修复document-script.get.desc.xml
<webscript> <shortname>get-document-data</shortname> <description>获取指定节点的属性值,支持返回子文件夹列表</description> <url>/get-document-data?nodeRef={nodeRef}&property={property}&includeChildren={includeChildren?}</url> <authentication>user</authentication> <format default="json"/> <family>Alfresco Script</family> </webscript>
4 修复document-script.get.json.ftl(把原来的html后缀改成json,删除错误的list逻辑)
<#escape x as x?json_string> { "nodeRef": "${nodeRef}", "value": "${value}" <#if children??> ,"children": [ <#list children as child> { "nodeRef": "${child.nodeRef}", "name": "${child.name}" }<#if child_has_next>,</#if> </#list> ] </#if> } </#escape>
可选方案:不用模板,Java直接输出响应
如果你不需要模板,可以直接删除FTL文件,Java继承AbstractWebScript,直接往response写JSON即可,不会触发模板渲染的报错,核心修改点:
- 删除所有FTL文件
- Java代码中每次请求新建JSONObject,用
NodeService读取属性后直接输出到response,设置响应头Content-Type: application/json - desc.xml中保持format默认json即可
内容的提问来源于stack exchange,提问作者QazWsxEdc190721
相关产品推荐
相关产品推荐

