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