项目中,常常需要用到文件的上传和下载,上传和下载功能实际上是对Document对象进行insert和查询操作.本篇演示简单的文件上传和下载,理论上文件上传后应该将ID作为操作表的字段存储,这里只演示文件上传到Document对象中。
一.文件上传功能
apex代码
1 public with sharing class FileUploadUsedTransientController { 2 3 public transient Blob fileUploadBody{get;set;} 4 5 public String fileUploadName{get;set;} 6 7 public void uploadFile() { 8 Document uploadFileDocument = new Document(); 9 Boolean needInsert = false; 10 if(fileUploadBody != null && fileUploadBody.size() > 0) { 11 uploadFileDocument.body = fileUploadBody; 12 needInsert = true; 13 } 14 if(fileUploadName != null) { 15 uploadFileDocument.Name = fileUploadName; 16 needInsert = true; 17 } 18 19 if(needInsert) { 20 try { 21 uploadFileDocument.FolderId = '00528000002JyclAAC'; 22 insert uploadFileDocument; 23 ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.INFO,'上传成功')); 24 } catch(DmlException e) { 25 ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR,'上传失败')); 26 } 27 } else { 28 ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.WARNING,'无上传内容')); 29 } 30 } 31 }
这里Blob对象用来绑定前台的inputFile的value值,因为VF页面最大允许内存135K,所以Blob对象声明transient类型。如果上传一个超过135K的文件并且点击保存以后,
Blob对象不声明transient或者在insert以后不将Blob对象置为null,则页面将会超过135K,页面会崩溃。
相应VF代码:
1 <apex:page controller="FileUploadUsedTransientController"> 2 <apex:pageMessages /> 3 <apex:form > 4 <apex:inputFile value="{!fileUploadBody}" fileName="{!fileUploadName}"/> 5 <apex:commandButton value="上传" action="{!uploadFile}"/> 6 </apex:form> 7 </apex:page>
上述总结:以上代码只是演示最基本的上传功能,项目中通常一个sObject创建一个字段用来存储document的ID信息,当insert上传的Document以后将document的ID存储在sObject的字段中
注意:transient字段使用
可以在可串行化的顶级类中使用瞬态关键字,例如在控制器、控制器扩展或实现可批处理或可调度接口的类中。此外,还可以在定义可序列化类中声明的字段类型的类中使用瞬态。将变量声明为瞬态变量可以减小视图状态大小。瞬态关键字的一个常见用例是VisualForce页面上的字段,该字段仅在页请求的持续时间内使用,但不应成为页面视图状态的一部分,并且将使用过多的系统资源,在请求期间将多次重新计算。一些顶点对象自动被认为是短暂的,也就是说,它们的值不会被保存为页面视图状态的一部分。使用对象包扣:
- PageReferences
- XmlStream classes
- Collections automatically marked as transient only if the type of object that they hold is automatically marked as transient, such as a collection of Savepoints
- Most of the objects generated by system methods, such as Schema.getGlobalDescribe.
- JSONParser class instances
使用实例:
注意:静态变量也不会通过视图状态传输。上面的示例包含VisualForce页面和自定义控制器。单击页面上的“刷新”按钮将导致更新临时日期,因为每次刷新页面时都会重新创建该日期。非瞬态日期继续具有其原始值,该值已从视图状态反序列化,因此它保持不变
二.页面下载功能
文件上传自然便有文件下载或者文件预览功能,项目中通常在sObject中有一个字段存放Document的ID,那样可以直接通过记录来获取到相应的document的ID。SFDC提供了通过servlet方式下载相关document资源,访问方式为host/servlet/servlet.FileDownload?file=' + documentId
此处模拟通过传递documentId参数来实现下载的功能页面。
apex代码:
public with sharing class FileDownloadController { 2 3 public String documentId = ''; 4 5 public FileDownloadController() { 6 init(); 7 } 8 9 public Boolean showDownload{get;set;} 10 11 public FileDownloadController(ApexPages.StandardController controller) { 12 init(); 13 } 14 15 public void init() { 16 Map<String,String> paramMap = ApexPages.currentPage().getParameters(); 17 if(paramMap.get('documentId') != null) { 18 documentId = paramMap.get('documentId'); 19 showDownload = true; 20 } else { 21 showDownload = false; 22 } 23 } 24 25 public String downloadURL{ 26 get { 27 String urlBase = '/servlet/servlet.FileDownload?file=' + documentId; 28 return urlBase; 29 } 30 } 31 }
相应VF页面如下:
1 <apex:page controller="FileDownloadController"> 2 <apex:outputLink value="{!downloadURL}" rendered="{!showDownload == true}">下载</apex:outputLink> 3 </apex:page>