Java调用SharePoint REST API与Graph API实战指南
1. Java调用SharePoint地址的完整指南在企业级应用开发中与SharePoint的集成是一个常见需求。作为.NET生态中的文档管理和协作平台SharePoint提供了丰富的API接口而Java开发者同样可以通过多种方式与之交互。本文将详细介绍三种主流方法REST API调用、客户端库使用和第三方工具集成并附上完整代码示例和实战经验。重要提示无论采用哪种方式都需要提前在SharePoint管理员处申请API访问权限并确保网络策略允许跨平台调用。1.1 基础环境准备开始前需要确保Java 8开发环境推荐JDK 11 LTS版本Maven或Gradle构建工具有效的SharePoint Online或本地部署访问权限网络能够访问目标SharePoint站点企业内网通常需要配置代理建议在pom.xml中添加以下基础依赖dependencies !-- HTTP客户端 -- dependency groupIdorg.apache.httpcomponents/groupId artifactIdhttpclient/artifactId version4.5.13/version /dependency !-- JSON处理 -- dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId version2.13.3/version /dependency /dependencies2. 通过REST API直接调用SharePoint提供了完整的REST API接口这是最灵活也是兼容性最好的集成方式。2.1 认证流程实现现代SharePoint主要使用OAuth 2.0认证以下是获取访问令牌的典型代码public class SharePointAuth { private static final String AUTH_URL https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token; public String getAccessToken(String clientId, String clientSecret) throws IOException { CloseableHttpClient client HttpClients.createDefault(); HttpPost post new HttpPost(AUTH_URL); ListNameValuePair params new ArrayList(); params.add(new BasicNameValuePair(client_id, clientId)); params.add(new BasicNameValuePair(client_secret, clientSecret)); params.add(new BasicNameValuePair(grant_type, client_credentials)); params.add(new BasicNameValuePair(scope, https://graph.microsoft.com/.default)); post.setEntity(new UrlEncodedFormEntity(params)); HttpResponse response client.execute(post); // 解析JSON响应获取access_token ObjectMapper mapper new ObjectMapper(); JsonNode rootNode mapper.readTree(response.getEntity().getContent()); return rootNode.path(access_token).asText(); } }2.2 站点内容读取示例获取到访问令牌后可以调用SharePoint REST API读取文档库内容public class SharePointReader { public void listDocuments(String siteUrl, String accessToken) throws Exception { String apiUrl siteUrl /_api/web/lists/getbytitle(Documents)/items; CloseableHttpClient client HttpClients.createDefault(); HttpGet get new HttpGet(apiUrl); get.setHeader(Authorization, Bearer accessToken); get.setHeader(Accept, application/json;odataverbose); HttpResponse response client.execute(get); String responseBody EntityUtils.toString(response.getEntity()); // 使用Jackson解析返回的JSON数据 ObjectMapper mapper new ObjectMapper(); JsonNode root mapper.readTree(responseBody); JsonNode results root.path(d).path(results); results.forEach(item - { System.out.println(File: item.path(FileLeafRef).asText()); System.out.println(Modified: item.path(Modified).asText()); }); } }2.3 文件上传实现通过REST API上传文件的完整流程public void uploadFile(String siteUrl, String accessToken, String localPath, String remoteFolder) throws Exception { String fileName new File(localPath).getName(); String apiUrl siteUrl /_api/web/GetFolderByServerRelativeUrl( remoteFolder )/Files/add(url fileName ,overwritetrue); // 读取文件内容 byte[] fileContent Files.readAllBytes(Paths.get(localPath)); CloseableHttpClient client HttpClients.createDefault(); HttpPost post new HttpPost(apiUrl); post.setHeader(Authorization, Bearer accessToken); post.setHeader(Accept, application/json;odataverbose); post.setEntity(new ByteArrayEntity(fileContent)); HttpResponse response client.execute(post); if (response.getStatusLine().getStatusCode() 200) { System.out.println(Upload successful); } else { throw new RuntimeException(Upload failed: response.getStatusLine().getStatusCode()); } }3. 使用Microsoft Graph客户端库对于较新的SharePoint OnlineMicrosoft Graph提供了更现代的API接口。3.1 添加Graph SDK依赖dependency groupIdcom.microsoft.graph/groupId artifactIdmicrosoft-graph/artifactId version5.0.0/version /dependency dependency groupIdcom.microsoft.azure/groupId artifactIdmsal4j/artifactId version1.11.0/version /dependency3.2 使用GraphServiceClientpublic class GraphExample { private static final String CLIENT_ID your-client-id; private static final String TENANT_ID your-tenant-id; private static final String CLIENT_SECRET your-client-secret; public GraphServiceClientRequest getGraphClient() throws Exception { ConfidentialClientApplication app ConfidentialClientApplication.builder( CLIENT_ID, ClientCredentialFactory.createFromSecret(CLIENT_SECRET)) .authority(https://login.microsoftonline.com/ TENANT_ID /) .build(); ClientCredentialParameters params ClientCredentialParameters.builder( Collections.singleton(https://graph.microsoft.com/.default)) .build(); IAuthenticationResult result app.acquireToken(params).join(); return GraphServiceClient.builder() .authenticationProvider(request - { request.addHeader(Authorization, Bearer result.accessToken()); }) .buildClient(); } public void listSharePointSites(GraphServiceClientRequest client) { SiteCollectionPage sites client.sites() .buildRequest() .get(); sites.getCurrentPage().forEach(site - { System.out.println(Site: site.displayName); System.out.println(URL: site.webUrl); }); } }4. 使用第三方库Microsoft SharePoint Java Client对于需要更高级功能的场景可以考虑使用第三方库。4.1 添加依赖dependency groupIdcom.microsoft.sharepoint/groupId artifactIdsharepoint-client/artifactId version1.1.0/version /dependency4.2 基本操作示例public class SharePointClientExample { public void basicOperations() throws Exception { SharePointCredentials credentials new SharePointOnlineCredentials( usernamedomain.com, password.toCharArray()); SharePointClient client new SharePointClient( https://yourdomain.sharepoint.com/sites/yoursite, credentials); // 获取文档库 List documents client.getList(Documents); // 上传文件 File uploadFile new File(localfile.docx); client.uploadFile(documents.getRootFolder(), uploadFile.getName(), new FileInputStream(uploadFile)); // 下载文件 File downloadFile new File(downloaded.docx); client.downloadFile(documents.getRootFolder() /sample.docx, new FileOutputStream(downloadFile)); } }5. 实战经验与问题排查5.1 常见错误及解决方案认证失败(401 Unauthorized)检查Azure AD应用注册的API权限是否包含SharePoint相关权限确认客户端密钥未过期验证租户ID和客户端ID是否正确跨域访问问题在SharePoint管理员中心添加Java应用所在域为可信域对于SPFX开发需配置CORS策略大文件上传超时使用分块上传API增加HTTP超时设置示例分块上传代码public void uploadLargeFile(String siteUrl, String accessToken, String localPath, String remotePath) { // 实现分块上传逻辑 }5.2 性能优化建议批量操作使用$batch端点合并多个请求示例批量查询String batchRequest --batch_request\n Content-Type: application/http\n Content-Transfer-Encoding: binary\n\n GET /_api/web/lists HTTP/1.1\n Accept: application/json;odataverbose\n\n --batch_request\n Content-Type: application/http\n Content-Transfer-Encoding: binary\n\n GET /_api/web/siteusers HTTP/1.1\n Accept: application/json;odataverbose\n\n --batch_request--;缓存策略对静态数据实现本地缓存使用ETag进行条件请求连接池配置PoolingHttpClientConnectionManager connManager new PoolingHttpClientConnectionManager(); connManager.setMaxTotal(100); connManager.setDefaultMaxPerRoute(20); CloseableHttpClient client HttpClients.custom() .setConnectionManager(connManager) .build();6. 高级功能实现6.1 文档版本控制public void getFileVersions(String fileUrl, String accessToken) throws Exception { String apiUrl fileUrl /versions; CloseableHttpClient client HttpClients.createDefault(); HttpGet get new HttpGet(apiUrl); get.setHeader(Authorization, Bearer accessToken); get.setHeader(Accept, application/json;odataverbose); HttpResponse response client.execute(get); String responseBody EntityUtils.toString(response.getEntity()); // 解析版本信息 ObjectMapper mapper new ObjectMapper(); JsonNode versions mapper.readTree(responseBody) .path(d).path(results); versions.forEach(version - { System.out.println(Version: version.path(VersionLabel).asText()); System.out.println(Modified: version.path(Modified).asText()); }); }6.2 搜索功能集成public void searchSharePoint(String query, String accessToken) throws Exception { String apiUrl https://yourdomain.sharepoint.com/_api/search/query ?querytext URLEncoder.encode(query, UTF-8) ; CloseableHttpClient client HttpClients.createDefault(); HttpGet get new HttpGet(apiUrl); get.setHeader(Authorization, Bearer accessToken); get.setHeader(Accept, application/json;odataverbose); HttpResponse response client.execute(get); String responseBody EntityUtils.toString(response.getEntity()); // 处理搜索结果 ObjectMapper mapper new ObjectMapper(); JsonNode results mapper.readTree(responseBody) .path(d).path(query).path(PrimaryQueryResult) .path(RelevantResults).path(Table).path(Rows) .path(results); results.forEach(item - { System.out.println(Title: item.path(Cells).path(results).get(0) .path(Value).asText()); System.out.println(Path: item.path(Cells).path(results).get(6) .path(Value).asText()); }); }在实际项目中根据具体需求选择合适的集成方式。对于简单的文件操作REST API足够使用复杂业务场景可考虑Graph API或第三方库。关键是要处理好认证流程和异常情况确保系统稳定可靠。

相关新闻

从零基础到网络安全专家的系统学习路径

从零基础到网络安全专家的系统学习路径

1. 从黑客梦到安全专家的真实成长路径 十年前,我在大学宿舍里看着《黑客帝国》电影,被那些在虚拟世界无所不能的"黑客"形象深深吸引。当时以为学会几个炫酷的命令就能成为安全专家,直到真正入行后才明白:网络安全是门需…

2026/10/11 0:58:57 阅读更多 →
akvcam高级配置:自定义图像控制与格式转换技巧

akvcam高级配置:自定义图像控制与格式转换技巧

akvcam高级配置:自定义图像控制与格式转换技巧 【免费下载链接】akvcam akvcam, virtual camera for Linux 项目地址: https://gitcode.com/gh_mirrors/ak/akvcam akvcam是一款功能强大的Linux虚拟摄像头驱动,通过灵活的配置选项和丰富的图像处理…

2026/10/6 3:09:24 阅读更多 →
Home Assistant深度界面定制:hass-config实战指南

Home Assistant深度界面定制:hass-config实战指南

Home Assistant深度界面定制:hass-config实战指南 【免费下载链接】hass-config ✨ A different take on designing a Lovelace UI (Dashboard) 项目地址: https://gitcode.com/gh_mirrors/ha/hass-config 在智能家居生态系统中,Home Assistant作…

2026/10/5 9:59:09 阅读更多 →

最新新闻

有界与冻结:对话系统跨会话记忆双闸设计实战

有界与冻结:对话系统跨会话记忆双闸设计实战

在对话系统和大模型应用里摸爬滚打久了,你迟早会撞上一个尴尬场景:用户上周明明跟你聊过“家里小孩对花生过敏”,这周回来你热情推荐了一款含花生碎的曲奇配方。用户没发火,但你心里清楚——这个系统失忆了。跨会话记忆不是什么新…

2026/10/15 5:25:11 阅读更多 →
CGRect

CGRect

苹果给同一个矩形类型起NSRect和CGRect两个名字,核心是‌历史演进跨平台兼容框架边界‌三重原因,并非简单的重复定义。🕰️ 历史起源:两个独立框架的产物‌NSRect‌ 诞生于早期的 NeXTSTEP 系统,属于 ‌Foundation/App…

2026/10/15 5:25:10 阅读更多 →
易语言乐玩插件FindPicEx多图查找实战:从单图到批量识别

易语言乐玩插件FindPicEx多图查找实战:从单图到批量识别

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 5:25:10 阅读更多 →
在MCU上复刻阿波罗导航计算机:AGC指令集仿真与嵌入式实现

在MCU上复刻阿波罗导航计算机:AGC指令集仿真与嵌入式实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 5:25:10 阅读更多 →
纯整数二阶滤波器:嵌入式MCU上实现高效ADC信号处理

纯整数二阶滤波器:嵌入式MCU上实现高效ADC信号处理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 5:25:10 阅读更多 →
虚拟机Ubuntu部署OpenClaw与Ollama:搭建私有本地AI代理

虚拟机Ubuntu部署OpenClaw与Ollama:搭建私有本地AI代理

上个月我又被一份云端 API 账单气到不行:只是让 AI 助手帮我写点小脚本、整理几份日志,月底一算居然够我吃好几顿火锅。更别扭的是,工作内容还要先经过别人家的服务器转一圈,数据隐私这块始终心里没底。于是我开始认真琢磨一件事—…

2026/10/15 5:24:10 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →