如何处理BLOB类型数据之一:上传文件并保存到BLOB中

实验环境:JDeveloper 11.1.2.0.0。 

1. 实验准备:创建Schema  
(1)sqlplus system/welcome1 @create_neverland_user.sql 
grant connect, resource to neverland identified by neverland; 
Exit; 
(2)sqlplus neverland/neverland @create_neveland_table.sql 
DROP SEQUENCE uploaded_files_seq; 
DROP TABLE uploaded_files; 
CREATE TABLE uploaded_files( 
id NUMBER PRIMARY KEY, 
filename VARCHAR2(80), 
content BLOB, 
date_created DATE); 
CREATE SEQUENCE uploaded_files_seq; 
CREATE TRIGGER assign_file_id BEFORE INSERT ON uploaded_files FOR EACH ROW 
BEGIN 
SELECT uploaded_files_seq.NEXTVAL INTO :NEW.id FROM dual; 
END; 



2. 使用ADF BC创建Model层  
(1)修改EO的ID字段的属性,因为使用Sequence,所以要改成Sequence类型。 

(2)修改EO的DateCreate字段的属性,Insert时自动插入当前日期。 

(3)定制化AM对应的java类,添加自定义方法:saveUploadedFileToBlob。 
public void saveUploadedFileToBlob(BlobDomain content, String fileName) { 
UploadedFilesViewImpl uploadedFileVO = (UploadedFilesViewImpl)getUploadedFilesView1(); 
UploadedFilesViewRowImpl newRow = (UploadedFilesViewRowImpl)uploadedFileVO.createRow(); 
uploadedFileVO.insertRow(newRow); 
newRow.setContent(content); 
newRow.setFilename(fileName); 
getDBTransaction().commit(); 


(4)新增一个新的VO:Last5UploadedFilesView,用于显示最新上传的5个文件。 
其中添加了一个自动计算字段:文件大小字段。 



3. 创建一个新页面:upload_file_to_blob.jspx,核心代码如下:  
(1) 
 

valueChangeListener="#{myBackingBean.inputFile_valueChangeListener}"/> 
 
 
(2)拖放Last5UploadedFilesView,生成Table,设置Table的Partial Trigger指向Upload按钮。 
(3)设置Last5UploadedFilesView1Iterator的Refresh属性=ifNeeded。 
(4)增加一个action Binding:Last5UploadedFilesView1Iterator的Execute操作。 

4. 对应的Manage Bean的核心代码如下:  
// 点击Upload按钮时,先调用此方法,因为ValueChange事件先于actionListener事件 。 
public void inputFile_valueChangeListener(ValueChangeEvent event) { 
UploadedFile file = (UploadedFile)event.getNewValue(); 
if (file != null && file.getLength() > 0) { 
String message = 
"Successfully uploaded file '" + file.getFilename() + "' (" + file.getLength() + " bytes)"; 
popupMessage(event, message); 
try { 
AppModule am = (AppModule)getDefaultApplicationModule(); 
am.saveUploadedFileToBlob(writeInputStreamToBlobDomain(file.getInputStream()), file.getFilename()); 
} catch (Exception e) { 
e.printStackTrace(); 




// 点击Upload按钮时,执行完valueChangeListener后,调用此方法 
public void uploadButton_actionListener(ActionEvent actionEvent) { 
if (this.getInputFileComponent().getValue() != null) { 
// 清空InputFile,这样符合中国人的习惯。 
inputFileComponent.setValue(null); 
// 刷新VO:Last5UploadedFilesView,这样是为了保证从“底层”更新VO。 
BindingContainer bindings = getBindings(); 
OperationBinding operationBinding = bindings.getOperationBinding("Execute"); 
operationBinding.execute(); 
} else { 
popupMessage(actionEvent, Not_Valid_FileName_Message); 



5. 为了保证只显示最新上传的5个文件,需要修改AM的Java类,Override方法:create:  
protected void create() { 
super.create(); 
getLast5UploadedFilesView1().setMaxFetchSize(5); 


6. 运行页面,上传文件。  


Project下载: UploadFileToBlob.7z  

问题1:选择某些文件时,明明文件存在,但上传时却报告:java.io.IOException: 系统找不到指定的路径。  
解决方法: 
其实是web.xml中配置选项:org.apache.myfaces.trinidad.UPLOAD_MAX_MEMORY的问题。 
该参数的含义是上载时可以使用的最大内存,改成5M后,就可以了。原来我给的是500K,无法上传大于1M的文件,会报出该异常。 
另一个参数:org.apache.myfaces.trinidad.UPLOAD_MAX_DISK_SPACE的含义是允许上传的最大文件。我这里给的也是5M。可以根据需要修改。 
为了保证上传效率,这两个参数需要配合着修改。 

 
 
org.apache.myfaces.trinidad.UPLOAD_MAX_MEMORY 
 
5120000 
 
 
 
org.apache.myfaces.trinidad.UPLOAD_MAX_DISK_SPACE 
 
5120000 
 
 
 
org.apache.myfaces.trinidad.UPLOAD_TEMP_DIR 
 
/tmp/TrinidadUploads/ 
 

参考文献: 
1.http://thepeninsulasedge.com/blog/?p=6 
2.http://thepeninsulasedge.com/blog/?p=50 
3.http://blogs.oracle.com/smuenchadf/examples/#85 
4.http://cn.forums.oracle.com/forums/thread.jspa?messageID=4013464 
5.http://forums.oracle.com/forums/thread.jspa?threadID=983109 
6.http://forums.oracle.com/forums/thread.jspa?threadID=934144 

7.http://kr.forums.oracle.com/forums/thread.jspa?threadID=858909

http://maping930883.blogspot.com/2011/07/adf090adf-bcblobblob.html

你可能感兴趣的:(马平ADF,ADF)