Hello all
This post is about a very simple requirement -file handling (uploading and downloading various types of file) in ADF and it is needed very often to store file in absolute server path (actual path) and download from there and I have posted about that previously
Uploading and downloading files from absolute server path
Now this post is about uploading and saving file in database BLOB column and downloading from there
See step by step implementation -
Cheers :) Happy Learning
This post is about a very simple requirement -file handling (uploading and downloading various types of file) in ADF and it is needed very often to store file in absolute server path (actual path) and download from there and I have posted about that previously
Uploading and downloading files from absolute server path
Now this post is about uploading and saving file in database BLOB column and downloading from there
See step by step implementation -
- Created a simple table in HR schema to store uploaded file name ,path ,content type and file in BLOB column See sql script for this table-
- Then prepare model using this table and drop on page as af:table, and an af:inputFile component to select and upload file
- Then create a ValueChangeListener on inputFile component to create new row in table and upload file to database
- Now run and check application , Drop single or multiple files in af:inputFile component
- Check in DB table, all records are saved with file in BLOB :)
- I have seen that developers often use servlet to download and open file in browser window using HTTP response , but no need to to do this as ADF provides built in component for this <af:fileDownloadActionListener> that automatically generate http response
- Now Upload part is complete , for download functionality added a link in table column and dropped an af:fileDownloadActionListener inside link and set properties for DownloadActionListener
- See Download Listener Code
CREATE TABLE FILE_UPD_DWN ( FILE_NAME VARCHAR2(50 BYTE), PATH VARCHAR2(100 BYTE), CONTENT_TYPE VARCHAR2(500 BYTE), IMAGE_FILE BLOB )
Packages Used
import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.sql.SQLException; import java.util.List; import javax.faces.context.FacesContext; import javax.faces.event.ValueChangeEvent; import oracle.adf.model.BindingContext; import oracle.adf.model.binding.DCIteratorBinding; import oracle.adf.view.rich.util.ResetUtils; import oracle.binding.BindingContainer; import oracle.binding.OperationBinding; import oracle.jbo.ViewObject; import oracle.jbo.domain.BlobDomain; import org.apache.myfaces.trinidad.model.UploadedFile; import upddwd.model.view.FileUpdDwnVORowImpl;
Bean method to upload file in database
/**Method to upload file in Database * @return */ public String UploadFileActionToDB(UploadedFile file) { UploadedFile myfile = file; if (myfile != null) { //Get current row of viewObject using iterator DCIteratorBinding imageIter = (DCIteratorBinding) getBindingsCont().get("FileUpdDwn1Iterator"); ViewObject vo = imageIter.getViewObject(); FileUpdDwnVORowImpl curRow = (FileUpdDwnVORowImpl) vo.getCurrentRow(); try { //Save image in Blob column in database curRow.setImageFile(createBlobDomain(myfile)); } catch (Exception ex) { System.out.println("Exception-" + ex); } } return null; } /**Method to create blobdomain for uploaded file * */ private BlobDomain createBlobDomain(UploadedFile file) { InputStream in = null; BlobDomain blobDomain = null; OutputStream out = null; try { in = file.getInputStream(); blobDomain = new BlobDomain(); out = blobDomain.getBinaryOutputStream(); byte[] buffer = new byte[8192]; int bytesRead = 0; while ((bytesRead = in.read(buffer, 0, 8192)) != -1) { out.write(buffer, 0, bytesRead); } in.close(); } catch (IOException e) { e.printStackTrace(); } catch (SQLException e) { e.fillInStackTrace(); } return blobDomain; }
AMImpl method to insert record in DB table for new file
/**Method to set file path and name * @param name * @param path */ public void setFileData(String name, String path, String contTyp) { ViewObject fileVo = this.getFileUpdDwn1(); Row newRow = fileVo.createRow(); newRow.setAttribute("FileName", name); newRow.setAttribute("Path", path); newRow.setAttribute("ContentType", contTyp); fileVo.insertRow(newRow); }
AMImpl method to check for duplicate file record in DB table
/**Method to check for duplicate files * @param fileNm * @return */ public String checkDuplicateFile(String fileNm) { ViewObject fileVo = this.getFileUpdDwn1(); Row duplFile[] = fileVo.getFilteredRows("FileName", fileNm); if (duplFile.length > 0) { return "N"; } else { return "Y"; } }
ValueChangeListener to execute all methods
/** * Generic Method to execute operation * */ public OperationBinding executeOperation(String operation) { OperationBinding createParam = getBindingsCont().getOperationBinding(operation); return createParam; } /**Method to Upload Multiple Files to DB ,called on ValueChangeEvent of inputFile * @param vce */ public void uploadFileVCE(ValueChangeEvent vce) { if (vce.getNewValue() != null) { //Get File Object from VC Event List<UploadedFile> lf = (List<UploadedFile>) vce.getNewValue(); //Traverse over file list to upload all files for (UploadedFile fileVal : lf) { //Method to check if this file is uploaded previously or not OperationBinding duplOb = executeOperation("checkDuplicateFile"); duplOb.getParamsMap().put("fileNm", fileVal.getFilename()); duplOb.execute(); if (duplOb.getResult() != null && "Y".equalsIgnoreCase(duplOb.getResult().toString())) { //Method to insert data in table to keep track of uploaded files OperationBinding ob = executeOperation("setFileData"); ob.getParamsMap().put("name", fileVal.getFilename()); ob.getParamsMap().put("path", "DB"); ob.getParamsMap().put("contTyp", fileVal.getContentType()); ob.execute(); //Upload and Save file to DB UploadFileActionToDB(fileVal); //Commit the transaction executeOperation("Commit").execute(); //Execute ViewObjecy executeOperation("Execute").execute(); } } // Reset inputFile component after upload ResetUtils.reset(vce.getComponent()); } }
/**Method to download file from actual path * @param facesContext * @param outputStream */ public void downloadFileListener(FacesContext facesContext, OutputStream outputStream) throws IOException { DCIteratorBinding imageIter = (DCIteratorBinding) getBindingsCont().get("FileUpdDwn1Iterator"); ViewObject vo = imageIter.getViewObject(); FileUpdDwnVORowImpl curRow = (FileUpdDwnVORowImpl) vo.getCurrentRow(); BlobDomain blob = curRow.getImageFile(); BufferedInputStream in = null; in = new BufferedInputStream(blob.getBinaryStream()); int b; byte[] buffer = new byte[10240]; while ((b = in.read(buffer, 0, 10240)) != -1) { outputStream.write(buffer, 0, b); } outputStream.close(); }
Cheers :) Happy Learning
Thanks for this simple and informational tutorial, I am learning Oracle ADF from your blog only
ReplyDeleteKeep up the good work
Thanks a lot
Additionally you can move through the reviews expressed by the users such as you to get the good quality of service and the downloaded files. VPN for omegle.com
ReplyDeleteHi I Followed your code, by Clicking on Download Link, page is hanging and if I refresh the page It is downloading......after that page is hanging then refresh it comes to normal...How can I resolve this
ReplyDeleteHi I am facing the below error while doing the file upload to blob column (oracle table), the version of the jdeveloper we are using 12.2.1.2.0.
ReplyDeletejava.sql.SQLSyntaxErrorException: ORA-00932: inconsistent datatypes: expected - got BLOB
I followed the same steps which you mentioned. I created the same table and tried too. Please suggest what might be the reason?
Have you checked attached sample application ?
DeleteThis worked for me. Blob column marked as key attribute in EO. After removing that it worked. Thank you
Deleteits work with me for all version previous than ADF 12.2.1.3 .
ReplyDeletebut ADF 12.2.1.3 version have problem that says " no more data to read from socket " .
The import upddwd.model.view.FileUpdDwnVORowImpl;
ReplyDeletedoesn't work here.
Some one help me.
Have you created RowImpl class of viewobject in your project ?
DeleteThis comment has been removed by the author.
ReplyDeleteHi Ashish,
ReplyDeleteWhile testing it is giving error in weblogic 10.3.6 server like below,
"cannot create an object of type:java.sql.blob from type:oralce.jbo.domain.blobdomain with value".
Could you please help converting domain.blobdomain type to sql.blob type.
Thanks.