Search code examples
oracle-adfjdeveloperoracle-appsapplication-framework

OAF - Download file from server


I have a requirement to allow user to enter server path and file name and download file.
I used the below code to serve the purpose:

HttpServletResponse response = (HttpServletResponse) pageContext.getRenderingContext().getServletResponse();

File fileToDownload = null;
try
{
  fileToDownload = new File(filePath);
}
catch (Exception e)
{
  throw new OAException("Invalid File Path or file does not exist.");
}

response.setContentType(fileType);
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
response.setContentLength((int)fileToDownload.length());

InputStream in = null;
ServletOutputStream outs = null;

try
{
  outs = response.getOutputStream();
  in = new BufferedInputStream(new FileInputStream(fileToDownload));
  int ch;
  while ((ch = in.read()) != -1)
  {
    outs.write(ch);
  }
}catch (IOException e)
{
  // TODO
  e.printStackTrace();
}finally
  {
    try
    {
      outs.flush();
      outs.close();
      if (in != null)
      {
        in.close();
      }
    }catch (Exception e)
    {
      e.printStackTrace();
    }
  }

The issue with this is, that any file greater than 48KB, when downloaded appends an extra line in it.

The method for using messageDownload item mentioned in Developer's guide is not clear enough. It mentions a VO. What should be the query of this VO? How do we insert file in this table to be used in this VO?

Please suggest a solution.


Solution

  • I finally resolved my query.
    I have used messageDownload Bean to serve the purpose.

    1. If the file is not stored anywhere in DB, then create a new LOB table. Otherwise, the existing LOB table can be used and only 3rd step will be needed. Create LOB table:
    > CREATE TABLE xx_LOBS (   FILE_ID            NUMBER        
    > PRIMARY KEY,   FILE_CONTENT_TYPE  VARCHAR2(100)         NOT NULL,  
    > FILE_DATA          CLOB ) LOB (FILE_DATA) STORE AS 
    >       ( TABLESPACE  APPS_TS_MEDIA 
    >         ENABLE      STORAGE IN ROW
    >         CHUNK       32768
    >         PCTVERSION  10
    >         NOCACHE
    >         STORAGE    (
    >                     INITIAL          128K
    >                     NEXT             128K
    >                     MINEXTENTS       1
    >                     MAXEXTENTS       2147483645
    >                     PCTINCREASE      0
    >                     BUFFER_POOL      DEFAULT
    >                    )
    >       ) ;
    
    1. Now, to insert the file into this LOB table, I used a procedure which I called in OAF page itself. Point to note here is, the directory used in BFILENAME function must be an existing directory in all_directories or dba_directories.
    CREATE OR REPLACE PROCEDURE xx_to_clob_proc (p_dir       IN VARCHAR2
                                                  , p_file_name IN VARCHAR2
                                                  , ret_code    OUT VARCHAR2
                                                  , ret_msg     OUT VARCHAR2)
        IS                                                
        v_bfile   BFILE;
        v_clob    CLOB;
    BEGIN
        v_bfile := BFILENAME (p_dir, p_file_name);
    
      BEGIN
          IF DBMS_LOB.FILEEXISTS (v_bfile) = 1 THEN
              DBMS_LOB.OPEN(v_bfile);
              DBMS_LOB.CREATETEMPORARY (v_clob, TRUE, DBMS_LOB.SESSION);
              DBMS_LOB.LOADFROMFILE (v_clob, v_bfile, DBMS_LOB.GETLENGTH (v_bfile));
              DBMS_LOB.CLOSE (v_bfile);
    
              INSERT INTO xx_LOBS VALUES(FILE_ID_SEQ.NEXTVAL,'text/html', v_clob);
    
          END IF;
          ret_code := 'S';
          ret_msg := 'File stored in LOB table';
          COMMIT;
      EXCEPTION
          when others then
              ret_code := 'E';
              ret_msg := 'Error: File not generated.' ||sqlerrm;
              rollback;
    
      END;
    
    EXCEPTION
        when others then
            ret_code := 'E';
            ret_msg := 'Error: ' ||sqlerrm;
            INSERT INTO xx_LOBS VALUES(FILE_ID_SEQ.NEXTVAL,'ERROR', EMPTY_CLOB());
            COMMIT;
    
    END;
    
    1. Now, in OAF page, add messageDownload item and specify the below:
      View instance: VO with query for LOB table
      View attribute: VO Attribute having file name
      MIME type : Either hard-code it to 'text/html' or make it dynamic as in DevGuide
      File View Attr: VO Attribute having file data
      Data type: CLOB

    I have added an input field for file path and file name. Then, on click on GO button, the step 2 Procedure is called and the messageDownload item VO is executed accordingly.

    Please let me know, in case of any queries.