调用SharePoint API上传文件返回400 Bad Request错误
问题排查与修复方案
调用SharePoint接口返回400 Bad Request是代码存在多处不符合接口规范的问题,具体问题点和修复方式如下:
现存问题
- 请求方法与接口不匹配:
/_api/web/GetFolderByServerRelativeUrl是GET类型查询接口,仅用来查询已存在的文件夹信息,不具备创建文件夹的能力,代码中用POST方法调用该接口不符合规范。 - 参数格式错误:接口要求传入未编码的服务器相对路径,代码中提前将路径中的空格转义为
%20做了URL编码,会触发参数校验失败。 - 逻辑错误:拼接完请求URL后存在一行提前return的调试代码,会直接终止方法执行,后续的请求发送逻辑根本无法运行。
- 缺少必填请求头:所有SharePoint REST API请求都需要携带指定的Accept和Content-Type头,代码中仅配置了Authorization头,缺少必填项。
- 接口选型错误:要实现“文件夹存在则返回信息、不存在则自动创建”的逻辑,不应使用GetFolderByServerRelativeUrl接口,应使用原生支持该能力的
EnsureFolder接口。
修复后代码示例
String siteURL = "https://mycompany.sharepoint.com/sites/sitename"; // 不要对路径做提前URL编码,直接传原始相对路径 String folderUrl = "Shared Documents/MS upload test"; //===============================================// //Sharepoint API 自动检查/创建目标路径 //===============================================// // 调用EnsureFolder接口实现存在即返回、不存在即创建的逻辑 String url1w = siteURL + "/_api/web/GetFolderByServerRelativeUrl('" + folderUrl + "')/EnsureFolder"; // 删除原代码中提前return的调试代码 URL urlcw = new URL(url1w); URLConnection con1 = urlcw.openConnection(); HttpURLConnection httpCon1 = (HttpURLConnection) con1; httpCon1.setDoOutput(true); httpCon1.setDoInput(true); httpCon1.setRequestMethod("POST"); httpCon1.setRequestProperty("Authorization", "Bearer " + accessToken); // 补全SharePoint REST API必填请求头 httpCon1.setRequestProperty("Accept", "application/json;odata=nometadata"); httpCon1.setRequestProperty("Content-Type", "application/json;odata=nometadata"); // 不需要传请求体时直接获取输出流后关闭即可 DataOutputStream wr1 = new DataOutputStream(httpCon1.getOutputStream()); wr1.flush(); wr1.close(); // 读取响应 String respStr1 = ""; if (httpCon1.getResponseCode() == 200) { respStr1 = "Path has been found/created successfully. ResponseCode : " + httpCon1.getResponseCode(); } else { // 建议这里读取错误流获取具体报错详情,方便排查问题 respStr1 += "Error while writing file, ResponseCode : " + httpCon1.getResponseCode() + " "+ httpCon1.getResponseMessage(); } return respStr1;
额外注意事项
- 确保获取accessToken时申请了SharePoint相关的正确权限,比如Sites.ReadWrite.All权限,否则会返回401/403错误。
- 如果后续要做文件上传,小文件可以直接调用上传接口,大文件建议用分片上传接口,避免请求超时。
内容的提问来源于stack exchange,提问作者Rohit Jaiswal
相关产品推荐
相关产品推荐

