This post is about to upload single file/multiple files from the client to the server and store the data in a BLOB column in Database.
First of all, we have to create a table to store files in database:
CREATE TABLE "HR"."DOCUMENTS"
(
"DOCUMENT_ID" NUMBER NOT NULL ENABLE,
"DOCUMENT_NAME" VARCHAR2(50 BYTE),
"DOCUMENT_TYPE" VARCHAR2(100 BYTE),
"DOCUMENT_FILE" BLOB,
CONSTRAINT "DOCUMENTS_PK" PRIMARY KEY ("DOCUMENT_ID")
)
Single file upload
Below is the UI for single file upload with a table with uploaded files along with the download button for each file.
Steps to achieve single file uploading:
1. Add inputFile component on jspx page:
<af:inputFile label="Upload File" id="if1"
binding="#{pageFlowScope.SingleFileUploadDownloadBean.inputFile}"
valueChangeListener="#{pageFlowScope.SingleFileUploadDownloadBean.onFileUploadVCL}"
autoSubmit="true"/>
Add a button to trigger the action to upload the File:
<af:commandButton text="Upload" id="cb1"
disabled="#{pageFlowScope.SingleFileUploadDownloadBean.inputFile.value == null ? true : false}"
partialTriggers="if1"
actionListener="#{pageFlowScope.SingleFileUploadDownloadBean.onFileUpload}"
partialSubmit="true"/>
2. Drag and drop the DocumentsVO on page as Adf Table. Remove the Blob column from the table and add a new column in UI to enable File downloading:
//Comment out or remove Blob Column from the table
<!--<af:column sortProperty="DocumentFile" sortable="false"
headerText="#{bindings.DocumentsVO1.hints.DocumentFile.label}"
id="c1">
<af:inputText value="#{row.bindings.DocumentFile.inputValue}"
label="#{bindings.DocumentsVO1.hints.DocumentFile.label}"
required="#{bindings.DocumentsVO1.hints.DocumentFile.mandatory}"
columns="#{bindings.DocumentsVO1.hints.DocumentFile.displayWidth}"
maximumLength="#{bindings.DocumentsVO1.hints.DocumentFile.precision}"
shortDesc="#{bindings.DocumentsVO1.hints.DocumentFile.tooltip}"
id="it1">
<f:validator binding="#{row.bindings.DocumentFile.validator}"/>
</af:inputText>
</af:column>-->
//Add new Column to add Download button in each row
<af:column id="c1" width="413"
headerText="File Download">
<af:commandButton text="Download File" id="cb3">
<af:fileDownloadActionListener contentType="#{row.bindings.DocumentType.inputValue}"
filename="#{row.bindings.DocumentName.inputValue}"
method="#{pageFlowScope.SingleFileUploadDownloadBean.downloadFile}"/>
</af:commandButton>
</af:column>
3. In ManagedBean : (Here bean name is SingleFileUploadDownloadBean)
private RichInputFile inputFile;
private String fileName;
private String contentType;
private UploadedFile file;
private BlobDomain blob;
// Value Change Listener for inputFileComponent
public void onFileUploadVCL(ValueChangeEvent valueChangeEvent) {
file = (UploadedFile)valueChangeEvent.getNewValue();
// Get the file name
fileName = file.getFilename();
// get the mime type
contentType = file.getContentType();
// get blob
blob=getBlob(file);
}
// Method to get Blob
public BlobDomain getBlob(UploadedFile file){
InputStream in = null;
BlobDomain blobDomain = null;
OutputStream out = null;
try
{
in = file.getInputStream();
blobDomain = new BlobDomain();
out = blobDomain.getBinaryOutputStream();
IOUtils.copy(in, out);
}
catch (IOException e)
{
e.printStackTrace();
}
catch (SQLException e)
{
e.fillInStackTrace();
}
return blobDomain;
}
//Method to invoke Operation binding to upload file in database
public void onFileUpload(ActionEvent actionEvent) {
DCBindingContainer bc = ADFUtil.getBindingContainer();
OperationBinding operationbinding = bc.getOperationBinding("uploadFiletoDB");
if(operationbinding!=null){
operationbinding.getParamsMap().put("fileName", fileName);
operationbinding.getParamsMap().put("contentType", contentType);
operationbinding.getParamsMap().put("blob", blob);
operationbinding.execute();
}
System.out.println("File uploaded successfully");
if (inputFile != null) {
inputFile.resetValue();
inputFile.setValid(true);
}
}
//Method to download File
Note: Make sure that Row Selection must be single and in SelectionListener should be present in ADF table on jspx page:
public void downloadFile(FacesContext facesContext,
OutputStream outputStream) {
DCBindingContainer bindings = ADFUtil.getBindingContainer();
DCIteratorBinding iteratorbinding =
bindings.findIteratorBinding("DocumentsVO1Iterator");
BlobDomain blob =
(BlobDomain)iteratorbinding.getCurrentRow().getAttribute("DocumentFile");
try {
IOUtils.copy(blob.getInputStream(), outputStream);
blob.closeInputStream();
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
Multiple files upload :
Here we can add multiple inputFile component on click of Add Attachment button and remove the same by clicking Remove Attachment button. By default one inputFile component will be displayed. And after uploading single/multiple files, on click of Upload Files button, the uploaded files will be stored in database.
Steps to achieve multiple files uploading:
1. We will use forEach to add multiple inputFile component
<af:forEach items="#{pageFlowScope.MultipleFileUploadDownloadBean.rowFields}" var="row">
<af:inputFile label="Upload File" id="if2"
binding="#{pageFlowScope.MultipleFileUploadDownloadBean.map['FIELD'].inputFile}"
autoSubmit="true"
valueChangeListener="#{pageFlowScope.MultipleFileUploadDownloadBean.onFileUploadVCL}"
partialTriggers="cb5"/>
</af:forEach>
//Add attachment Button to create new inputFile at runtime
<af:commandButton text="Add Attachment" id="cb4"
actionListener="#{pageFlowScope.MultipleFileUploadDownloadBean.onAddFile}"/>
2. We will create a separate class to create Multiple inputFile component:
import oracle.adf.view.rich.component.rich.input.RichInputFile;
public class FileUpload {
private RichInputFile inputFile;
public FileUpload() {
super();
}
public void setInputFile(RichInputFile inputFile) {
this.inputFile = inputFile;
}
public RichInputFile getInputFile() {
return inputFile;
}
}
3. In ManagedBean:
private List fileNameList = new ArrayList();
private List fileContentTypeList = new ArrayList();
private List fileBlobList = new ArrayList();
private List fileSizeList = new ArrayList();
private List<HashMap> fieldlist = new ArrayList<HashMap>();
private HashMap<String, FileUpload> map;
private int fileCounter = 0;
//In constructor add below code to add single inputFile component on first time page load
public MultipleFileUploadDownloadBean() {
map = new HashMap<String, FileUpload>();
try {
FileUpload test = new FileUpload();
map.put("FIELD", test);
fieldlist.add(map);
} catch (Exception e) {
e.printStackTrace();
}
}
// Method to create new InputFile on UI
public void onAddFile(ActionEvent actionEvent) {
map = new HashMap<String, FileUpload>();
try {
FileUpload inputFile = new FileUpload();
map.put("FIELD", inputFile);
fieldlist.add(map);
} catch (Exception e) {
e.printStackTrace();
}
}
//Method to remove inputFile on UI
public void onRemoveFile(ActionEvent actionEvent) {
if (fieldlist.size() > 1) {
fieldlist.remove(fieldlist.size() - 1);
}
}
//Value Change Listener for inputFile
public void onFileUploadVCL(ValueChangeEvent valueChangeEvent) {
UploadedFile file;
file = (UploadedFile)valueChangeEvent.getNewValue();
fileNameList.add(file.getFilename());
fileContentTypeList.add(file.getContentType());
fileSizeList.add(file.getLength());
fileBlobList.add(getBlob(file));
// file counter to limit no of files that can be uploaded
fileCounter++;
}
// Method to invoke Operation binding to upload multiple files in database
public void onFileUpload(ActionEvent actionEvent) {
DCBindingContainer bc = ADFUtil.getBindingContainer();
OperationBinding operationbinding =
bc.getOperationBinding("uploadMultipleFilestoDB");
if (operationbinding != null) {
operationbinding.getParamsMap().put("fileNameList", fileNameList);
operationbinding.getParamsMap().put("fileContentTypeList",
fileContentTypeList);
operationbinding.getParamsMap().put("fileBlobList", fileBlobList);
operationbinding.execute();
}
System.out.println("File uploaded successfully");
}
Find the sample app here
First of all, we have to create a table to store files in database:
CREATE TABLE "HR"."DOCUMENTS"
(
"DOCUMENT_ID" NUMBER NOT NULL ENABLE,
"DOCUMENT_NAME" VARCHAR2(50 BYTE),
"DOCUMENT_TYPE" VARCHAR2(100 BYTE),
"DOCUMENT_FILE" BLOB,
CONSTRAINT "DOCUMENTS_PK" PRIMARY KEY ("DOCUMENT_ID")
)
Single file upload
Below is the UI for single file upload with a table with uploaded files along with the download button for each file.
Steps to achieve single file uploading:
1. Add inputFile component on jspx page:
<af:inputFile label="Upload File" id="if1"
binding="#{pageFlowScope.SingleFileUploadDownloadBean.inputFile}"
valueChangeListener="#{pageFlowScope.SingleFileUploadDownloadBean.onFileUploadVCL}"
autoSubmit="true"/>
Add a button to trigger the action to upload the File:
<af:commandButton text="Upload" id="cb1"
disabled="#{pageFlowScope.SingleFileUploadDownloadBean.inputFile.value == null ? true : false}"
partialTriggers="if1"
actionListener="#{pageFlowScope.SingleFileUploadDownloadBean.onFileUpload}"
partialSubmit="true"/>
2. Drag and drop the DocumentsVO on page as Adf Table. Remove the Blob column from the table and add a new column in UI to enable File downloading:
//Comment out or remove Blob Column from the table
<!--<af:column sortProperty="DocumentFile" sortable="false"
headerText="#{bindings.DocumentsVO1.hints.DocumentFile.label}"
id="c1">
<af:inputText value="#{row.bindings.DocumentFile.inputValue}"
label="#{bindings.DocumentsVO1.hints.DocumentFile.label}"
required="#{bindings.DocumentsVO1.hints.DocumentFile.mandatory}"
columns="#{bindings.DocumentsVO1.hints.DocumentFile.displayWidth}"
maximumLength="#{bindings.DocumentsVO1.hints.DocumentFile.precision}"
shortDesc="#{bindings.DocumentsVO1.hints.DocumentFile.tooltip}"
id="it1">
<f:validator binding="#{row.bindings.DocumentFile.validator}"/>
</af:inputText>
</af:column>-->
//Add new Column to add Download button in each row
<af:column id="c1" width="413"
headerText="File Download">
<af:commandButton text="Download File" id="cb3">
<af:fileDownloadActionListener contentType="#{row.bindings.DocumentType.inputValue}"
filename="#{row.bindings.DocumentName.inputValue}"
method="#{pageFlowScope.SingleFileUploadDownloadBean.downloadFile}"/>
</af:commandButton>
</af:column>
3. In ManagedBean : (Here bean name is SingleFileUploadDownloadBean)
private RichInputFile inputFile;
private String fileName;
private String contentType;
private UploadedFile file;
private BlobDomain blob;
// Value Change Listener for inputFileComponent
public void onFileUploadVCL(ValueChangeEvent valueChangeEvent) {
file = (UploadedFile)valueChangeEvent.getNewValue();
// Get the file name
fileName = file.getFilename();
// get the mime type
contentType = file.getContentType();
// get blob
blob=getBlob(file);
}
// Method to get Blob
public BlobDomain getBlob(UploadedFile file){
InputStream in = null;
BlobDomain blobDomain = null;
OutputStream out = null;
try
{
in = file.getInputStream();
blobDomain = new BlobDomain();
out = blobDomain.getBinaryOutputStream();
IOUtils.copy(in, out);
}
catch (IOException e)
{
e.printStackTrace();
}
catch (SQLException e)
{
e.fillInStackTrace();
}
return blobDomain;
}
//Method to invoke Operation binding to upload file in database
public void onFileUpload(ActionEvent actionEvent) {
DCBindingContainer bc = ADFUtil.getBindingContainer();
OperationBinding operationbinding = bc.getOperationBinding("uploadFiletoDB");
if(operationbinding!=null){
operationbinding.getParamsMap().put("fileName", fileName);
operationbinding.getParamsMap().put("contentType", contentType);
operationbinding.getParamsMap().put("blob", blob);
operationbinding.execute();
}
System.out.println("File uploaded successfully");
if (inputFile != null) {
inputFile.resetValue();
inputFile.setValid(true);
}
}
//Method to download File
Note: Make sure that Row Selection must be single and in SelectionListener should be present in ADF table on jspx page:
public void downloadFile(FacesContext facesContext,
OutputStream outputStream) {
DCBindingContainer bindings = ADFUtil.getBindingContainer();
DCIteratorBinding iteratorbinding =
bindings.findIteratorBinding("DocumentsVO1Iterator");
BlobDomain blob =
(BlobDomain)iteratorbinding.getCurrentRow().getAttribute("DocumentFile");
try {
IOUtils.copy(blob.getInputStream(), outputStream);
blob.closeInputStream();
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
Multiple files upload :
Here we can add multiple inputFile component on click of Add Attachment button and remove the same by clicking Remove Attachment button. By default one inputFile component will be displayed. And after uploading single/multiple files, on click of Upload Files button, the uploaded files will be stored in database.
Steps to achieve multiple files uploading:
1. We will use forEach to add multiple inputFile component
<af:forEach items="#{pageFlowScope.MultipleFileUploadDownloadBean.rowFields}" var="row">
<af:inputFile label="Upload File" id="if2"
binding="#{pageFlowScope.MultipleFileUploadDownloadBean.map['FIELD'].inputFile}"
autoSubmit="true"
valueChangeListener="#{pageFlowScope.MultipleFileUploadDownloadBean.onFileUploadVCL}"
partialTriggers="cb5"/>
</af:forEach>
//Add attachment Button to create new inputFile at runtime
<af:commandButton text="Add Attachment" id="cb4"
actionListener="#{pageFlowScope.MultipleFileUploadDownloadBean.onAddFile}"/>
2. We will create a separate class to create Multiple inputFile component:
import oracle.adf.view.rich.component.rich.input.RichInputFile;
public class FileUpload {
private RichInputFile inputFile;
public FileUpload() {
super();
}
public void setInputFile(RichInputFile inputFile) {
this.inputFile = inputFile;
}
public RichInputFile getInputFile() {
return inputFile;
}
}
3. In ManagedBean:
private List fileNameList = new ArrayList();
private List fileContentTypeList = new ArrayList();
private List fileBlobList = new ArrayList();
private List fileSizeList = new ArrayList();
private List<HashMap> fieldlist = new ArrayList<HashMap>();
private HashMap<String, FileUpload> map;
private int fileCounter = 0;
//In constructor add below code to add single inputFile component on first time page load
public MultipleFileUploadDownloadBean() {
map = new HashMap<String, FileUpload>();
try {
FileUpload test = new FileUpload();
map.put("FIELD", test);
fieldlist.add(map);
} catch (Exception e) {
e.printStackTrace();
}
}
// Method to create new InputFile on UI
public void onAddFile(ActionEvent actionEvent) {
map = new HashMap<String, FileUpload>();
try {
FileUpload inputFile = new FileUpload();
map.put("FIELD", inputFile);
fieldlist.add(map);
} catch (Exception e) {
e.printStackTrace();
}
}
//Method to remove inputFile on UI
public void onRemoveFile(ActionEvent actionEvent) {
if (fieldlist.size() > 1) {
fieldlist.remove(fieldlist.size() - 1);
}
}
//Value Change Listener for inputFile
public void onFileUploadVCL(ValueChangeEvent valueChangeEvent) {
UploadedFile file;
file = (UploadedFile)valueChangeEvent.getNewValue();
fileNameList.add(file.getFilename());
fileContentTypeList.add(file.getContentType());
fileSizeList.add(file.getLength());
fileBlobList.add(getBlob(file));
// file counter to limit no of files that can be uploaded
fileCounter++;
}
// Method to invoke Operation binding to upload multiple files in database
public void onFileUpload(ActionEvent actionEvent) {
DCBindingContainer bc = ADFUtil.getBindingContainer();
OperationBinding operationbinding =
bc.getOperationBinding("uploadMultipleFilestoDB");
if (operationbinding != null) {
operationbinding.getParamsMap().put("fileNameList", fileNameList);
operationbinding.getParamsMap().put("fileContentTypeList",
fileContentTypeList);
operationbinding.getParamsMap().put("fileBlobList", fileBlobList);
operationbinding.execute();
}
System.out.println("File uploaded successfully");
}
Find the sample app here
Hi Bharat,
ReplyDeleteThank you for this great article! I've just noticed a small issue when I ran your Sample application. "Attribute DocumentId in AppModule.DocumentsVO1 is required." Is there something missing ?
Thank you again
Jerome,
DeleteTry this out:
Run the below script:
create sequence "HR"."DOCUMENTS_S" minvalue 1 maxvalue 999999
INCREMENT BY 1 START WITH 1;
In DepartmentEO.xml
Edit the entity attribute: DepartmentId
Select ValueType as Expression and provide the below value:
(new oracle.jbo.server.SequenceImpl('DOCUMENTS_S',object.getDBTransaction())).getSequenceNumber()
Now run the home.jspx
Nice stuff Bhaskar!!
ReplyDeleteThanks a lot...
ReplyDeleteNice job :)
Hi Bharat,
ReplyDeleteIs it possible to use af:inputFile inside the table?
Hi Aaron,
DeleteYes we can use af:inputFile inside ADF table.
Thanks
Hi,
ReplyDeleteNice post.but when i run the page it wont saved.so how can i save the uploaded file in some place.my requirement is when one user get login and used to upload a file,it would be saved and when the same user login the page,the old uploaded files would be appeared.so how can i reach this scenario.pls help me out.
Thanks,
G.Shilpa
HI Shilpa,
DeleteYou can use DB table to save uploaded file content in BLOB data type. Use the sample app I attached with above post and let me know if you face any issue.
Regards,
Bharat
Thanks !!!
ReplyDeletethank you very much,i need the application you did,My Email: wanganleichina@gmail.com
ReplyDeleteThanks again.
hi bharat,
ReplyDeletethanks for the sourcecode. But how to increase speed of upload when we upload files exceed size of 20MB
Hi Bharath,
ReplyDeleteCan u please provide me ADFutil also or please guid me where i can find it
Download ADFUtil from below location:
Deletehttps://bbhaskar.opendrive.com/files?Ml80MjE1OTY3OF9IaUhhYw
This comment has been removed by the author.
ReplyDeletehello, I can not download the example
ReplyDeletehi Bharat,
ReplyDeletethe Sample app link is broken, could you restore it?
or send it to my email id,My Email: vicbri@gmail.com
ReplyDeleteThis comment has been removed by the author.
ReplyDeletehi bharat
ReplyDeletei have try do this application in the same way as u did but i am getting an error in this line of code,can tell me y this error is occuringm i am getting error in Blobdomain getblob(UploadedFile file)
IOUtils.copy(in, out);
it is showing error as method not found
you need the Commons IO package in the version 2.0.1 you can download from the Apache Software Foundation apache web side
DeleteI have download the file and added to the librery through the jdev but even then it is showing red line under that statement..is there anything that I must do after adding the .jar file to the ilbrary,could u please help me what to after adding the file..there 2 files binary nad source which one to download.
Deletehi bharat can u send the application to my email kintali.kiran1989@gmail.com
ReplyDeleteHi
ReplyDeleteI did the same what you said. But when I run the app it showing "File loaded successfully". But i cant see it in table. I am getting "No data to display".
Please help me.
Thanks in advance
This comment has been removed by the author.
ReplyDeletehi bharat can u send the application to my email
ReplyDeletemehanashameed@gmail.com
hi bharat can you send your app to my email: lovetkh@yahoo.com.
ReplyDeleteThanks a lot.
Hi Bharat Bhaskar,
ReplyDeleteI did the same what you said. But when I run the app it showing "File loaded successfully". But i cant see it in table. I am getting "No data to display". and can you please send this application on nasiramin43@gmail.com ? Please!
Thanks in advance
hi bharat can you send your app to my email:caybachduong13@gmail.com.
ReplyDeleteThanks a lot.
hi,
ReplyDeletecan you please send this code on my mail id hopes.nitin@gmail.com
Thanks in advance :)
Hi Bharat Bhaskar,
ReplyDeleteCan you send your code to my email: wmurillodf@gmail.com
Thanks a lot!
Hi Bharat,
ReplyDeleteWould you be able to provide a download link to the sample app please? The current link is broken.
Thanks!
Hi,
ReplyDeleteThis is exactly what I was looking for but I could not download the example code. Can you please send the application to me (david.beck[at]gmail.com)? Thank you.
Hi,
ReplyDeleteCould you please send this samples for me. Thanks le171282[at]gmail.com
Thanks for your work.
ReplyDeleteCould you send me yours jdev project adfkho@gmail.com
KM
Hi bharat can you send your app to my email: msalimdayer@gmail.com
ReplyDeleteThanks
This comment has been removed by the author.
ReplyDeleteHi Bharat
ReplyDeleteCould you please send your app to sundaram.babu01@gmail.com
Hi Bharat,
ReplyDeleteCan you send me too the app please on max.makarovsky@gmail.com
Thank You
hi bharat can u send the application to my email n.n.sarma@gmail.com
ReplyDeleteHi Any update on this
DeleteHello,
ReplyDeleteThank you very much for the post, but the download link is broken.
Can you please send the app to shokeros@hotmail.co.uk ?
Kind regards
Onkar
Hi Bharat,
ReplyDeleteCan you please share the app with me. My Id is firdausayed@gmail.com
Thank you.
Hi Bharat,
ReplyDeleteCan you please share the app with me. My Id is ah.attieh@gmail.com
Thank you
Hi Bharat,
ReplyDeleteCould you please send me the app on ibrahimrefaat@gmail.com
Thanks so much.
Hi Bharat,
ReplyDeleteCould you please send me the app on sandip.wavhal@gmail.com
Thanks so much.
Hi Bharat,
ReplyDeleteCould You please send the application in my mail 24info.amar@gmail.com since the link which you have mentioned is broken.
Thanks a lot
Hi Bharat,
ReplyDeleteCould you please share the sample app as the link is broken.Thanks in advance.
Regards,
Abhijit
Hi Bharat,
ReplyDeleteI'm try to make this app working since a couple of days but can't get it...
I have problems with the binding that always return null so it didn't upload to the DB.
It is possible to share the sample app again ?
Best regards,
Stefan
Hi Bharat,
ReplyDeleteI am try to upload a file using the same code, but the data does not enter to the DB.There is no error and the message 'The file upload successfully' is printed. The 'operationbinding' variable return a null value. Please send this app to my mail 'kmgreeshma8@gmail.com'.
Regards,
Greeshma K M
Hi Bharat,
ReplyDeleteI am implemented single file upload and download in my application, but my requirement is upload same file again with version.
Dear Bharat
ReplyDeletethis link its not working can you send me sample on younies123@hotmail.com
appreciate your help
HI bharat,
ReplyDeleteiam trying to open the sample app but i cannot downalod the file.please i request you to send to my mail or if any one has the file pls forward to A.shiva77@gmail.com
Could you please send me the app on abid_med_ali@yahoo.fr
ReplyDeleteHi Bharat,
ReplyDeleteCould you please send me the app on najibnugroho@outlook.com
Thanks so much
Hi Bharat,
ReplyDeleteCould You please send the application in my mail 24443450@qq.com since the link which you have mentioned is broken.
Thanks a lot
how to show the error at frontend if no file present in managedBean .
ReplyDeleteor any IO error occurred then how to show customized error in screen.
Can you please send me the app at mrjdsk@gmail.com
ReplyDeleteThanks
Hi Bhaskar,
ReplyDeleteIf i am trying to download this application there is no particular file.
@@ File not found error.
Pls check once.
Thanks.
Rahul
Dear Bharat
ReplyDeletethis link its not working can you send me sample on sameh.agag.2010@gmail.com
Thank You
Hello Bharat, I guess the link you provided in this blog post is broken. Do you have the sample application uploaded somewhere else? Kindly let me know. Thank you.
ReplyDeleteHello Bharat,
ReplyDeleteAs Mahesh also said above, it would be wonderful if you still have this sample mbean somewhere or if you could send me a similar example at bogdan.bilcan@outlook.com, or update the post with new link.
Thank you.