Please disable your adblock and script blockers to view this page

Search this blog

Saturday 8 April 2017

Uploading and downloading files from database (BLOB) in Oracle ADF (12.1.3)

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 -



  • 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-

    CREATE TABLE FILE_UPD_DWN  
    (  
       FILE_NAME  VARCHAR2(50 BYTE), 
       PATH  VARCHAR2(100 BYTE), 
       CONTENT_TYPE  VARCHAR2(500 BYTE), 
       IMAGE_FILE  BLOB
    )
    


  • 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

  • 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());
            }
        }
    


  • 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

  •     /**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();
        }
    
Sample ADF Application- Download
Cheers :) Happy Learning

11 comments :

  1. Thanks for this simple and informational tutorial, I am learning Oracle ADF from your blog only
    Keep up the good work

    Thanks a lot

    ReplyDelete
  2. 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

    ReplyDelete
  3. Hi 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

    ReplyDelete
  4. Hi 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.


    java.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?

    ReplyDelete
    Replies
    1. Have you checked attached sample application ?

      Delete
    2. This worked for me. Blob column marked as key attribute in EO. After removing that it worked. Thank you

      Delete
  5. its work with me for all version previous than ADF 12.2.1.3 .
    but ADF 12.2.1.3 version have problem that says " no more data to read from socket " .

    ReplyDelete
  6. The import upddwd.model.view.FileUpdDwnVORowImpl;
    doesn't work here.
    Some one help me.

    ReplyDelete
    Replies
    1. Have you created RowImpl class of viewobject in your project ?

      Delete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Hi Ashish,

    While 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.

    ReplyDelete