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
相关产品推荐
相关产品推荐

