You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SAPUI5控制器触发下载时GET_STREAM方法报无效键谓词错误

问题:SAPUI5 UploadSet下载附件时出现"The request URI contains an invalid key predicate"错误

背景

基于GOS实现SAPUI5 UploadSet组件的附件上传、展示和下载功能,此前所有功能运行正常,仅在展示和下载逻辑上做了少量调整。

SAPUI5视图代码

<mvc:View
     controller="..controller.activity"
     xmlns="sap.m"
     xmlns:mvc="sap.ui.core.mvc"
     xmlns:upload="sap.m.upload">
     ...
     <upload:UploadSet
         id="uploadActivityAttachment"
         class="uploadActivityAttachment"
         instantUpload="true"
         uploadUrl="/sap/opu/odata/sap/ZTEST_ATTACHMENT_2_SRV/attachmentSet"
         mode="MultiSelect"
         multiple="true"
         beforeUploadStarts="onBeforeUploadStarts"
         uploadCompleted="onUploadCompleted"
         items="{attachmentData>/attachment}">
         <upload:toolbar>
              <OverflowToolbar>
                    <ToolbarSpacer />
                    <Button 
                        id="downloadSelectedButton"
                        text="Download selected"
                        press="onDownloadSelectedButton" />
              </OverflowToolbar>
         </upload:toolbar>
         <upload:items>
              <upload:UploadSetItem
                     fileName="{attachmentData>FileName}"
                     mediaType="{attachmentData>MimeType}"
                     enabledEdit="false"
                     visibleEdit="false"
                     enabledRemove="true"
                     visibleRemove="true"
                     removePressed="onRemoveAttachment"
                     thumbnailUrl="{attachmentData>ThumbnailUrl}">
                     <upload:statuses>
                          <ObjectStatus
                              title="Document Id"
                              text="{attachmentData>DocumentId}"
                              visible="false" />
                          <ObjectStatus
                              title="Uploaded by"
                              text="{attachmentData>CreatorName}" />
                          <ObjectStatus
                              title="On"
                              text="{attachmentData>FormattedDateTime}" />
                     </upload:statuses>
              </upload:UploadSetItem>
         </upload:items>
     </upload:UploadSet>
...
</mvc:View>

SAPUI5控制器下载逻辑代码

...
onDownloadSelectedButton: async function () {
    let itemDocId;
    const oUploadSet = this.getView().byId('uploadActivityAttachment');
    oUploadSet.getItems().forEach((item) => {
        if(item.getListItem().getSelected()) {
         itemDocId = item.getStatuses()[0].getText();                  
         item.setUrl(`/sap/opu/odata/sap/ZTEST_ATTACHMENT_2_SRV/attachmentSet('${itemDocId}')/$value`);
         item.download(true);
    }
    });
},
...

当前问题

此前GET_STREAM方法运行正常,现在触发下载时出现错误:

The request URI contains an invalid key predicate.

OData服务GET_STREAM方法实现

METHOD /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM.

    DATA LS_STREAM  TYPE TY_S_MEDIA_RESOURCE.
    DATA(LV_ENTITY_SET_NAME) = IO_TECH_REQUEST_CONTEXT->GET_ENTITY_SET_NAME( ).
    DATA(LT_KEYS) = IO_TECH_REQUEST_CONTEXT->GET_KEYS( ).

    CASE LV_ENTITY_SET_NAME.
      WHEN 'attachmentSet'.
        DATA: LV_DOCUMENT_ID TYPE DOCUMENTID,
              LV_FILENAME    TYPE SO_OBJ_DES.
        LV_DOCUMENT_ID = LT_KEYS[ NAME = 'DOCUMENT_ID' ]-VALUE.
        CALL FUNCTION 'Z_DOWNLOAD_ATTACHMENT'
          EXPORTING
            IV_DOCUMENT_ID = LV_DOCUMENT_ID
          IMPORTING
            EV_VALUE       = LS_STREAM-VALUE
            EV_MIME_TYPE   = LS_STREAM-MIME_TYPE
            EV_FILENAME    = LV_FILENAME.

        DATA LS_LHEADER TYPE IHTTPNVP.
        LV_FILENAME = ESCAPE( VAL = LV_FILENAME FORMAT = CL_ABAP_FORMAT=>E_URL ).
        LS_LHEADER-NAME = 'Content-Disposition'.
        LS_LHEADER-VALUE = 'outline; filename=”' && LV_FILENAME && '”;'.
        SET_HEADER( IS_HEADER = LS_LHEADER ).

        COPY_DATA_TO_REF( EXPORTING IS_DATA = LS_STREAM
                          CHANGING  CR_DATA = ER_STREAM ).

    ENDCASE.
  ENDMETHOD.

解决建议

1. 校验OData实体键名大小写匹配

OData服务的实体集attachmentSet的键字段定义是DOCUMENT_ID(大写),需确认:

  • 实体模型中键字段的名称是否与ABAP代码中LT_KEYS[ NAME = 'DOCUMENT_ID' ]的键名完全一致(OData默认区分大小写)
  • 若实体键定义为小写document_id,则ABAP代码中需同步修改键名匹配

2. 验证DocumentId值的有效性

  • 在前端onDownloadSelectedButton方法中添加日志,输出itemDocId的实际值,检查是否存在空值、特殊字符(如单引号、空格)导致URL格式错误
  • 若itemDocId包含单引号,需做转义处理:
    itemDocId = itemDocId.replace(/'/g, "''");
    

3. 修正Content-Disposition头的错误

当前代码中Content-Disposition使用了错误的指令outline,应改为attachment,且引号使用了中文全角格式,需替换为英文半角:

LS_LHEADER-VALUE = 'attachment; filename="' && LV_FILENAME && '"'.

错误的头信息可能间接导致请求解析异常。

4. 检查OData服务元数据定义

  • 确认attachmentSet的实体类型是否正确标记为媒体实体(HasStream="true")
  • 检查实体键字段的类型是否与DOCUMENTID类型匹配,避免因类型不兼容导致键解析失败

5. 手动构造URL测试

直接在浏览器中访问构造的URL(如/sap/opu/odata/sap/ZTEST_ATTACHMENT_2_SRV/attachmentSet('实际文档ID')/$value):

  • 若手动访问同样报错,说明问题出在OData服务端的键解析逻辑
  • 若手动访问正常,排查前端代码中item.setUrl的拼接逻辑是否存在隐藏问题

内容的提问来源于stack exchange,提问作者wildGhifari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:31:12