You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Citrix ShareFile API上传Blob文件生成0字节文件问题求助

解决Salesforce中通过REST API上传Blob到Citrix ShareFile时文件大小为0字节的问题

问题背景

通过REST API在Citrix ShareFile上传文件的流程分为4步:

  • 获取access_token
  • 获取文件夹URI确定上传目标
  • 获取Chunk Uri
  • 通过Chunk Uri上传文件

前3步执行完全正常,但第4步POST请求后,ShareFile中创建的文件大小为0字节。已在Postman中用form-data选择文件测试,上传功能正常,问题仅出现在上传Salesforce数据库中存储的Blob数据时(无法获取物理文件路径)。

正常执行的代码(前3步)

String fileName_m = 'a12.pdf';  

//  获取认证Token
HttpRequest req = new HttpRequest();    
req.setEndpoint('https://{server}.sf-api.com/oauth/token?grant_type=password&client_id={client_id}&client_secret={secret}&username={user_name}&password={password}!');        
req.setMethod('GET');            

Http http = new Http();        
HttpResponse response = http.send(req);                   
System.Debug(response.getBody());

Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
String token = '';
String refreshtoken = '';
if(response.getStatusCode() == 200){
 token = (String)results.get('access_token');
 refreshtoken = (String)results.get('refresh_token');
}

system.debug('token=' + token);

// 获取文件夹ID
HttpRequest req1 = new HttpRequest();    
req1.setEndpoint('https://{server}.sf-api.com/sf/v3/Items?$expand=Children');        
req1.setMethod('GET');   
req1.setHeader('Authorization','Bearer ' + token);       

Http http1 = new Http();        
HttpResponse response1 = http1.send(req1);                   
System.Debug(response1.getBody());

Map<String, Object> results1 = (Map<String, Object>)JSON.deserializeUntyped(response1.getBody());
String url = '';
if(response1.getStatusCode() == 200){
 url = (String)results1.get('url');
}

System.Debug('Folder Url ' + url);

// 获取Chunk URI    
HttpRequest req2 = new HttpRequest();    
String endPoint = url + '/Upload2'; 
req2.setEndpoint(endPoint);        
req2.setMethod('POST');   
req2.setHeader('Authorization','Bearer ' + token);    
req2.setHeader('Content-Type', 'application/x-www-form-urlencoded');

String payload1 = 'FileName='+fileName_m;    
req2.setBody(payload1);

Http http2 = new Http();        
HttpResponse response2 = http2.send(req2);                   

Map<String, Object> results2 = (Map<String, Object>)JSON.deserializeUntyped(response2.getBody());
String ChunkUri = '';
if(response2.getStatusCode() == 200){
 ChunkUri = (String)results2.get('ChunkUri');
}

System.Debug('ChunkUri' + ChunkUri);

出现问题的上传代码

// 问题出在这里,无法正常工作
// 上传文件
Attachment att = [SELECT Id, Body, Name, ContentType FROM Attachment WHERE Id='00P3p00001XNLOHEA5'];
String body = EncodingUtil.base64Encode(att.body); 

List<Attachment> cvList = [SELECT Id, Body, Name, ContentType FROM Attachment WHERE Id='00P3p00001XNLOHEA5'];
String attachmentBody = EncodingUtil.base64Encode(cvList[0].Body);
Blob pdfBlob = EncodingUtil.base64Decode(attachmentBody);

system.debug('pdfBlob' + pdfBlob);

HttpRequest req3 = new HttpRequest();    
req3.setEndpoint(ChunkUri);        
req3.setMethod('POST');   
req3.setHeader('Authorization','Bearer ' + token);   

req3.setHeader('Content-Length', String.valueOf(attachmentBody.length()));
req3.setHeader('Content-Encoding', 'UTF-8');
req3.setHeader('Content-type', 'application/pdf');
req3.setHeader('Connection', 'keep-alive');
req3.setBodyAsBlob(pdfBlob);

Http http3 = new Http();        
HttpResponse response3 = http3.send(req3);                   
System.Debug(response3.getBody());

解决方案

1. 修正Content-Length计算错误

当前代码用attachmentBody.length()(Base64字符串长度)作为Content-Length,但实际应该用Blob的原始字节长度,也就是pdfBlob.size()。ShareFile会根据Content-Length判断接收的字节数,长度不匹配会导致只接收0字节。

2. 移除不必要的Content-Encoding头

你上传的是原始PDF二进制数据,不是UTF-8编码的文本,Content-Encoding: UTF-8会导致ShareFile解析错误,应该删除这个头。

3. 简化Blob获取逻辑

不需要重复查询Attachment并进行Base64编码解码,直接使用查询到的Blob即可,减少冗余操作。

修正后的上传代码

// 修正后的上传文件代码
Attachment att = [SELECT Id, Body, Name, ContentType FROM Attachment WHERE Id='00P3p00001XNLOHEA5'];
Blob pdfBlob = att.Body;

HttpRequest req3 = new HttpRequest();    
req3.setEndpoint(ChunkUri);        
req3.setMethod('POST');   
req3.setHeader('Authorization','Bearer ' + token);   
req3.setHeader('Content-Length', String.valueOf(pdfBlob.size()));
req3.setHeader('Content-type', att.ContentType); // 使用Attachment自带的ContentType更准确
req3.setBodyAsBlob(pdfBlob);

Http http3 = new Http();        
HttpResponse response3 = http3.send(req3);                   
System.Debug(response3.getBody());

额外验证点

  • 确认Chunk Uri是否包含正确的上传参数(如文件大小、分片信息),如果是大文件可能需要分块上传,但小文件场景下当前逻辑足够。
  • 检查Salesforce的Attachment是否确实有有效数据(att.Body.size()大于0),避免源Blob本身为空。

内容的提问来源于stack exchange,提问作者Noor A Shuvo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 04:20:32