如何编写Java代码实现Egnyte分片上传并调用Egnyte REST API
Java实现Egnyte分片上传(调用REST API)
我来帮你梳理如何用Java实现Egnyte的分片上传,结合官方Chunked Upload API规范,我会修正并完善你提供的代码示例,同时解释关键要点:
核心流程说明
Egnyte的分片上传需要三个核心步骤才能完成:
- 初始化分片上传:先调用API获取唯一的上传ID,用于后续所有分片的关联
- 逐个上传分片:按固定大小拆分本地文件,依次上传每个分片,带上分片编号和字节范围信息
- 完成上传:所有分片上传成功后,触发合并操作,让服务器生成最终文件
完整代码实现(修正并完善版)
import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; public class EgnyteChunkedUploader { // 替换为你的Egnyte配置信息 private static final String EGNYTE_API_BASE = "https://your-domain.egnyte.com/pubapi/v1/fs"; private static final String AUTH_TOKEN = "your-valid-auth-token"; private static final String EGNYTE_TARGET_PATH = "/Shared/Uploads/"; // 上传到Egnyte的目标目录 public ResponseEntity<String> uploadFileChunked(File localFile) throws Exception { // 1. 第一步:初始化分片上传,获取上传ID String initUploadUrl = EGNYTE_API_BASE + "/chunked" + EGNYTE_TARGET_PATH + localFile.getName(); HttpHeaders initHeaders = buildEgnyteRequestHeaders(); ResponseEntity<String> initResponse = new RestTemplate().exchange( initUploadUrl, HttpMethod.POST, new HttpEntity<>(initHeaders), String.class ); // 从响应中解析uploadId(实际项目建议用JSON解析库,比如Jackson) String uploadId = extractUploadId(initResponse.getBody()); // 2. 第二步:分片上传配置与执行 long totalFileSize = localFile.length(); // 修正原代码错误:获取文件实际大小而非磁盘总空间 int chunkSize = 1024 * 1024; // 1MB分片大小,官方建议范围1MB-5GB byte[] chunkBuffer = new byte[chunkSize]; int partNumber = 1; // Egnyte分片编号从1开始 ResponseEntity<String> chunkUploadResponse = null; // try-with-resources自动关闭流,避免资源泄漏 try (FileInputStream fis = new FileInputStream(localFile); BufferedInputStream bis = new BufferedInputStream(fis)) { int bytesRead; while ((bytesRead = bis.read(chunkBuffer)) > 0) { // 构建当前分片的上传URL String chunkUrl = EGNYTE_API_BASE + "/chunked" + EGNYTE_TARGET_PATH + localFile.getName() + "/" + uploadId + "/" + partNumber; // 设置分片请求头,关键是Content-Range告知服务器分片范围 HttpHeaders chunkHeaders = buildEgnyteRequestHeaders(); long startByte = (long) (partNumber - 1) * chunkSize; long endByte = Math.min(startByte + bytesRead - 1, totalFileSize - 1); chunkHeaders.add("Content-Range", String.format("bytes %d-%d/%d", startByte, endByte, totalFileSize)); // 构建带分片数据的请求实体 HttpEntity<byte[]> chunkEntity = new HttpEntity<>(chunkBuffer, chunkHeaders); // 上传当前分片 chunkUploadResponse = new RestTemplate().exchange( chunkUrl, HttpMethod.POST, chunkEntity, String.class ); partNumber++; } } // 3. 第三步:完成上传,触发服务器合并分片 String completeUploadUrl = EGNYTE_API_BASE + "/chunked" + EGNYTE_TARGET_PATH + localFile.getName() + "/" + uploadId; HttpHeaders completeHeaders = buildEgnyteRequestHeaders(); ResponseEntity<String> completeResponse = new RestTemplate().exchange( completeUploadUrl, HttpMethod.PUT, new HttpEntity<>(completeHeaders), String.class ); return completeResponse; } // 构建Egnyte请求头,包含认证和内容类型 private HttpHeaders buildEgnyteRequestHeaders() { HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Bearer " + AUTH_TOKEN); headers.add("Content-Type", "application/octet-stream"); return headers; } // 从初始化响应中提取uploadId(示例实现,需根据实际响应格式调整) private String extractUploadId(String responseBody) { // 假设响应格式为{"uploadId": "xxxx-xxxx-xxxx"},实际用JSON库更可靠 int startIdx = responseBody.indexOf("uploadId") + 10; int endIdx = responseBody.indexOf("\"", startIdx); return responseBody.substring(startIdx, endIdx); } }
关键细节解释
- 初始化上传的必要性:必须先获取
uploadId,否则服务器无法识别多个分片属于同一个文件 - Content-Range头:这是Egnyte识别分片的核心,必须准确设置当前分片在整个文件中的字节范围
- 分片编号规则:必须从1开始,且连续无缺失,否则合并操作会失败
- 资源管理:用
try-with-resources确保文件流自动关闭,避免内存泄漏
额外注意事项
- 确保你的认证令牌拥有目标目录的上传权限
- 实际项目中需要添加异常处理(比如网络重试、分片上传失败重试)
- 分片大小可根据网络情况调整,但不要超出官方建议的范围
内容的提问来源于stack exchange,提问作者Udhayam P
相关产品推荐
相关产品推荐

