如何从Word Office Add-in向Spring Boot后端传输DriveItem标识?
Java Spring Boot后端与Angular Word Add-in集成:关联OneDrive DriveItem方案
问题背景
我用Java Spring Boot构建后端服务,Angular开发Word Office Add-in,当前流程:
- 后端通过Microsoft Graph SDK for Java创建DriveItem并上传Word文档到用户OneDrive
- 用户被重定向至文档的webUrl,在新标签页打开文档
需求:点击Add-in中的按钮时,将文档标识信息传给后端,让后端能定位到对应的DriveItem。
已尝试方案及问题
- 查询参数方案:后端在webUrl中添加DocumentId参数,但
Office.context.document.url不返回查询字符串,无法获取该参数 - 自定义属性方案:后端将DocumentId加入ListItem的
FieldsValueSet,但不确定Office.context.document.getFilePropertiesAsync()能否读取这类属性 - Graph shares()方法方案:后端想用Graph SDK的
shares()方法,需传入编码后的webUrl,但不确定Office JS返回的Office.context.document.url能否解析出对应DriveItem
可行解决方案
1. 自定义文档属性方案(明确可行)
后端将DriveItem ID存入文档本身的自定义属性(而非ListItem的字段),Add-in可通过Office JS直接读取:
- 后端上传文档时设置自定义属性:
// 获取目标DriveItem DriveItem driveItem = graphServiceClient.me().drive().items(driveItemId) .buildRequest() .select("id") .get(); // 添加自定义属性 HashMap<String, Object> properties = new HashMap<>(); properties.put("CustomDriveItemId", driveItem.getId()); graphServiceClient.me().drive().items(driveItemId).properties() .buildRequest() .patch(properties); - Add-in读取自定义属性:
注意:不要使用ListItem的Office.context.document.customProperties.getAsync((result) => { if (result.status === Office.AsyncResultStatus.Succeeded) { const driveItemId = result.value.get("CustomDriveItemId"); // 将ID传给后端 } });FieldsValueSet,那是SharePoint列表项的属性,而非文档自身属性,Office JS的customProperties仅对应文档自定义属性。
2. Graph shares()方法(完全可行)
Office.context.document.url返回的完整文档webUrl可直接编码后用于Graph的shares()接口:
- Add-in获取文档URL并传给后端:
const docUrl = Office.context.document.url; // 将docUrl传给后端 - 后端用Graph SDK解析:
该方案无需提前存储任何信息,仅通过文档URL即可反向定位DriveItem,兼容性极强。// 按Graph规则编码URL:先encodeURIComponent,再Base64编码,最后添加前缀"u!" String encodedUrl = "u!" + Base64.getUrlEncoder().encodeToString(URLEncoder.encode(docUrl, StandardCharsets.UTF_8).getBytes(StandardCharsets.UTF_8)); DriveItem driveItem = graphServiceClient.shares(encodedUrl).driveItem() .buildRequest() .get(); // 拿到driveItem后即可进行后续操作
3. Add-in直接调用Graph API获取DriveItem ID
若Add-in已获取对应权限(如Files.Read),可直接在前端调用Graph API获取DriveItem信息,再将ID传给后端:
Office.context.document.getFilePropertiesAsync((result) => { if (result.status === Office.AsyncResultStatus.Succeeded) { const fileUrl = result.value.url; // 编码URL并调用Graph接口 const encodedUrl = `u!${btoa(encodeURIComponent(fileUrl))}`; fetch(`https://graph.microsoft.com/v1.0/shares/${encodedUrl}/driveItem`, { headers: { "Authorization": "Bearer " + accessToken // 从Add-in身份验证流程获取token } }) .then(res => res.json()) .then(data => { const driveItemId = data.id; // 将ID传给后端 }); } });
此方案无需后端提前设置任何属性,直接通过Graph API获取信息,流程最直接。
最佳实践
- 优先使用Graph shares()方法:无需提前存储或设置属性,仅靠文档URL即可定位DriveItem,兼容性和可维护性最优
- 自定义属性作为备选:若因权限限制无法调用Graph API,或需传递额外自定义信息时使用,注意区分文档属性与列表项属性
- 放弃URL参数方案:Office JS不返回URL查询字符串,该方案从底层逻辑上不可行
- 权限最小化:后端和Add-in均申请最小必要权限,比如后端用
Files.ReadWrite,Add-in调用Graph用Files.Read即可 - 缓存关联信息:若后端需频繁操作同一文档,可将DriveItem ID与用户ID关联缓存,减少Graph API调用次数
内容的提问来源于stack exchange,提问作者stackoverflow_user_
相关产品推荐
相关产品推荐

