14 Replies Latest reply on Sep 24, 2012 11:07 AM by raks

    Download a file (stored in database) within webpage

    uwe72

      Hi there,

       

      i have to upload files from the user to the database. This works fine already.

       

      But now i want to give the user the opportunity to download this file on the webpage.

       

      I want a "download" Button, and when the user clicks, the file should be downloaded in the browser.

       

      How can i do this?

       

      Thank you!

       

      Regards!!!

      Uwe

        • 1. Download a file (stored in database) within webpage
          ilya40umov
          • 2. Download a file (stored in database) within webpage
            uwe72

            Thanks a lot, i will try it out. Until now i tried like this, but doesn't work:

             

            <a4j:commandButtonvalue="Download"title="Download"

                 ajaxSingle="true"action="#{utilityEditController.doDownload}"/>

             

             

             

             

                public void doDownload() {

                   byte[] csvData =createByteArray4File(selectedUploadItem.getFile());

                   FacesContext context = FacesContext.getCurrentInstance();

                   HttpServletResponse response = (HttpServletResponse)           FacesContext.getCurrentInstance().getExternalContext()

                           .getResponse();

                   response.setHeader("Content-disposition","attachment; filename= test.jpg");

                   response.setContentLength(csvData.length);

                   response.setContentType(selectedUploadItem.getContentType());

                   try {

                       response.getOutputStream().write(csvData);

                       response.getOutputStream().flush();

                       response.getOutputStream().close();

                       context.responseComplete();

                   } catch (IOException e) {

                       e.printStackTrace();

                   }

                }

            • 3. Download a file (stored in database) within webpage
              rdtesti

              A very simple way to do that (after you click the download button):

              • Send a request to server;
              • Instead processing the request and return a html to the client; you can process the request and return the FILE itself, but you will have to make some changes to you Response object:
              1.    response.setContentType("application/octet-stream");  /* This will download as binary (even if you are downloading txt... you can check mimetypes for other code */
              2.    response.addHeader("content-disposition", "attachment; filename=" + filename ); /* with your file name */
              3.    response.setContentLength((int)file.length()); /* The size you can get from DB */
              4.     ServletOutputStream out = response.getOutputStream();
              5.    Inside a loop {  out.write(file content)   }

               

               

              That is it!

              Hope it helps

              Rodolpho

              • 4. Download a file (stored in database) within webpage
                ilya40umov

                Don't use a4j:commandButton. Use h:commandButton instead.

                • 5. Download a file (stored in database) within webpage
                  uwe72

                  Ok, i changed the code:

                   

                  <h:commandButton value="Download" title="Download"  id="btnDownload"

                                           action="#{utilityEditController.doDownload}" />

                   

                   

                      public void doDownload() {

                          FacesContext context = FacesContext.getCurrentInstance();

                          HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext()

                                  .getResponse();

                          response.addHeader("content-disposition", "attachment; filename=" + "test.jpg"); /* with your file name */

                          response.setContentType("application/octet-stream");

                          try {

                              byte[] buf = new byte[1024];

                              File file = selectedUploadItem.getFile();

                              long length = file.length();

                              BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));

                              ServletOutputStream out = response.getOutputStream();

                              response.setContentLength((int) length);

                              while ((in != null) && ((length = in.read(buf)) != -1)) {

                                  out.write(buf, 0, (int) length);

                              }

                              in.close();

                              out.close();

                   

                              response.getOutputStream().flush();

                              response.getOutputStream().close();

                              context.responseComplete();

                          } catch (IOException e) {

                              e.printStackTrace();

                          }

                      }

                   

                   

                  But still doesn't work. On IE i get no response, and in Firefox i am getting the response you can see below.

                  What i am doing wrong?

                   

                  THANKS in advance!

                   

                   

                   

                  JFIF   ``C                                                                C                                                                        "                    

                     

                   

                               }       !1A  Qa

                  "q 2 #B R$3br   

                       %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz                 

                     

                   

                         

                       w      !1  AQ

                  aq "2  B    #3R br

                  $4%    &'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz      ?5?

                    D<s

                  3öb}U?WGt[Y{N36<

                   

                  ^ ??-l7EfQk  $ _ Zg |<fg:5 Y#6W)N/  t<K ^ = MW?t  &Xf[Fkk VN-3~3|'' oo Wh y 6x   w $?+VI? g? ?X~v~s /

                  bsn   ?p xVk8 _o

                  v VoK.?UY  L  AYcG/ Nsbs  k! ?|'

                  ?35' ,n]/>"u?f< aC_ 6?[   AnZ??

                  6JtiZ~~eyd?e?v nmdg&qD)OM> S>4?? |_i# 4_ _cUK     '??]7 ?t+Y?['P?^_ mr?tQ}:T?! ut?(8Nmi  o-[ c?Vbs:n"yu\}JU051p 2x>Zk    <L *K   ca?^8xh* TR QST^ *F`FrR O m?'Dt ?8s

                  ~gy|lI# ? '? h) ?i'o}ou')T?=v?,'ciGq] ?H    -   6z ZM%??Ti2x?p~   : 16YU    + '.IHF#ij5i/mQs($k?g?Fv( ]/m/tc  o J7?&qD)OM?|>4j  /  ~ ix Gb--+X?5-SIX

                  [GBRKK.&] ?+5n?o_<?_&U>C4jOYb+%Ir!K

                  • 6. Download a file (stored in database) within webpage
                    bolsover

                    I had a very similar issue a year or so back and found a couple of issues..

                    Mimetype should be appropriately set for .jpg or .jpeg this should be 'image/jpeg'

                    I tested all these:

                    ID MIMETYPE

                    bmp image/bmp

                    class application/octet-streamx

                    css text/css

                    doc application/word

                    docm application/vnd.openxmlformats-application/vnd.ms-word.document.macroEnabled.12

                    docx application/vnd.openxmlformats-officedocument.wordprocessingml.document

                    dotm application/vnd.openxmlformats-application/vnd.ms-application/vnd.ms-word.template.macroEnabled.12

                    dotx application/vnd.openxmlformats-officedocument.wordprocessingml.template

                    exe application/octet-streamx

                    gif image/gif

                    htm text/html

                    html text/html

                    jpe image/jpeg

                    jpeg image/jpeg

                    jpg image/jpeg

                    mp2 video/mpeg

                    mp3 application/octet-streamx

                    mpa video/mpeg

                    mpe video/mpeg

                    mpeg video/mpeg

                    mpg video/mpeg

                    mpp application/vnd.ms-project

                    pdf application/pdf

                    pps application/vnd.ms-powerpoint

                    ppsx application/vnd.openxmlformats-officedocument.presentationml.slideshow

                    ppt application/vnd.ms-powerpoint

                    pptm application/vnd.ms-powerpoint.presentation.macroEnabled.12

                    pptx application/vnd.openxmlformats-officedocument.presentationml.presentation

                    rtf application/rtf

                    tif image/tiff

                    tiff image/tiff

                    txt text/plain

                    wcm application/vnd.ms-works

                    wdb application/vnd.ms-works

                    wks application/vnd.ms-works

                    wps application/vnd.ms-works

                    xla application/vnd.ms-excel

                    xlc application/vnd.ms-excel

                    xlm application/vnd.ms-excel

                    xls application/vnd.ms-excel

                    xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

                    xlt application/vnd.ms-excel

                    xlw application/vnd.ms-excel

                    zip application/x-zip-compressed

                     

                    For some file types e.g. .pdf, you need to call context.responseComplete(); at the end of the method once all data has been transferred - but called for all types.

                     

                    There are problems when it comes to handling very large files because the file has to be held in the server memory before it is send downstram; in practice, I limited the file size to 200Mb on a (virtual) server with 2Gb memory. I did sucessfull tests on 500Mb files - bit I wanted to ensure there was pleanty of headroom. 

                    • 7. Download a file (stored in database) within webpage
                      uwe72

                      so you mean i cannot always use:

                           response.setContentType("application/octet-stream");

                      ?

                       

                      i also would prefer that ALWAYS the FileSaveAsDialog appears.....i do not need to open the file "inline".

                       

                      what i can change in my code above to solve my problem?

                      • 8. Re: Download a file (stored in database) within webpage
                        rdtesti

                        Yes. You can use always octect-stream. It works.

                         

                        Try that:

                        response.addHeader("content-disposition", "attachment; filename=" + "\"test.jpg\""); /* with your file name */

                         

                         

                        It should work, but if not I will take a look on my code that is already working.

                        The system I had starts downloading all files no matter what they are (txt; pdf;jpg;exe;bin;zip...)

                         

                         

                        --

                        Rodolpho

                        • 9. Download a file (stored in database) within webpage
                          uwe72

                          Thanks Rodolpho...

                           

                          but is still everything the same..........

                           

                          can u pls have a look to your code ?

                           

                          Thanks a lot!!

                          Uwe

                          • 10. Download a file (stored in database) within webpage
                            rdtesti

                            Hi Uwe.

                             

                            In my JSP I have this line:

                            <h:commandLink type="submit" value="#{dataItem.attachName}" action="#{myBean.downloadAttachment}"/>

                             

                             

                            On MyBean:

                            public String downloadAttachment() {

                               HttpServletResponse response =

                                (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();

                               

                               try {

                                Item item = itemService.getById(Item.class, new Integer(this.Id).intValue()); // Just to get the correct data from DB --- use yours here

                                response.getOutputStream().write(item.getAttachData());

                               

                                response.setContentType("application");

                                response.setContentLength(item.getAttachData().length);

                                response.setHeader("Content-Disposition", "attachment;filename=\"" + item.getAttachName() + "\"");

                              

                                response.getOutputStream().flush();

                                response.getOutputStream().close();

                               

                                FacesContext.getCurrentInstance().responseComplete();

                               } catch (IOException exception) {

                                System.out.println(exception.getStackTrace());

                               }

                              }

                              return null;

                            }

                             

                             

                             

                            What I saw here, is "application" only. And the Header has some caption characters, try to use as I  used on code above.

                             

                            --

                            Rodolpho

                            • 11. Download a file (stored in database) within webpage
                              uwe72

                              Thanks to all!

                               

                              It is working now.....

                               

                              i don't know why,but it is just working when i place the download Button on a modal dialog. But this is OK for the moment.

                              • 12. Re: Download a file (stored in database) within webpage
                                raks

                                Hello,

                                 

                                I try your code to download a file stored in a database but it doesn't work.

                                In the JSF file, I must put a <a4j:commandLink, the <h:commandLink doesn't enter in the code of the MB class.

                                 

                                Here is the code in my Bean class:

                                public String downloadAttach(BigDecimal idAttachToLoad) throws IOException

                                    {

                                        for(GsoFormAttach gfa : formsMb.getCurrentForm().getGsoFormAttachs())

                                        {

                                            if(gfa.getIdAttach().equals(idAttachToLoad))

                                            {

                                                gsoformAttach = gfa;

                                                HttpServletResponse response =  (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();

                                                try

                                                {

                                                    response.getOutputStream().write(gfa.getBlobAttach());

                                                    response.setContentType("application/octet-stream");

                                                    response.setContentLength(gfa.getBlobAttach().length);

                                                    response.setHeader("Content-Disposition", "attachment;filename=\"" + gfa.getFileName() + "\"");

                                                    response.getOutputStream().flush();

                                                    response.getOutputStream().close();

                                                }                

                                                catch (IOException exception)

                                                {

                                                     Logger.getLogger(Cadre5Mb.class.getName()).log(Level.SEVERE, null, exception);

                                                }        

                                            }

                                        }

                                        return null;

                                    }

                                 

                                And I have this error:

                                java.lang.IllegalStateException: "getOutputStream()" has already been called for this answer

                                 

                                I try a lot of different method to download this file but always have an error like this. I have too the error:

                                java.net.SocketException: Connection reset by peer: socket write error

                                 

                                Can someone help me please?

                                • 13. Re: Download a file (stored in database) within webpage
                                  godoy

                                  Do not use <a4j:commandButton , try with <h:commandButton. Ajax request not write byte content.

                                  • 14. Re: Download a file (stored in database) within webpage
                                    raks

                                    It doesn't work. I say in my last post: "the <h:commandLink doesn't enter in the code of the MB class."

                                     

                                    When I click, I have the error:

                                    ClientAbortException:  java.net.SocketException: Connection reset by peer: socket write error