You need to enable JavaScript to run this app. Alfresco Java Web脚本获取文档属性运行报错问题排查求助
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 05:39:03