实验环境: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)
<af:form id="f1" usesUpload="true">
<af:inputFile label="File Name:" id="if1" binding="#{myBackingBean.inputFileComponent}"
valueChangeListener="#{myBackingBean.inputFile_valueChangeListener}"/>
<af:commandButton text="Upload" id="cb1" actionListener="#{myBackingBean.uploadButton_actionListener}"/>
</af:form>
(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。可以根据需要修改。
为了保证上传效率,这两个参数需要配合着修改。
<context-param>
<!-- Maximum memory per request (in bytes) -->
<param-name>org.apache.myfaces.trinidad.UPLOAD_MAX_MEMORY</param-name>
<!-- Use 5,000K -->
<param-value>5120000</param-value>
</context-param>
<context-param>
<!-- Maximum disk space per request (in bytes) -->
<param-name>org.apache.myfaces.trinidad.UPLOAD_MAX_DISK_SPACE</param-name>
<!-- Use 5,000K -->
<param-value>5120000</param-value>
</context-param>
<context-param>
<!-- directory to store temporary files -->
<param-name>org.apache.myfaces.trinidad.UPLOAD_TEMP_DIR</param-name>
<!-- Use a TrinidadUploads subdirectory of /tmp -->
<param-value>/tmp/TrinidadUploads/</param-value>
</context-param>
参考文献:
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
2 条评论:
in.read(buffer) doesn't work when you try to download the same file for the second time
thanks for your comments.
alread fix it. pls download and try again.
发表评论