4 Replies Latest reply on Mar 14, 2010 9:38 PM by ranophoenix

    JBoss 5.1 + getRealPath()

    ranophoenix

      Hi!


      That is my webapp root dir:


        C:\jboss5.1\default\deploy\myapp.war  
      



      I'm creating a file in my Seam component with code:


      ...
      //DEST_DIR = "/downloads"
      File tmpFile = new  File (((ServletContext) extCtx.getContext()).getRealPath(DEST_DIR + fileName));  
      ...
      



      But the file is ONLY created at VFS in JBoss:


         C:\jboss\default\deploy\tmp\5c4o1k1-qno93n-g6qxhtb3-1-g6qxidug-v\minhaapp.war\downloads\myfile.zip
      



      And this warn is generated:


      WARN  [AbstractVirtualFileHandler] No such existing handler, falling back to old root + path: vfsfile:/C:/jboss/default/deploy/minhaapp.war/downloads/myfile.zip  
      



      How to resolve this?


      Thanks in advance.

        • 1. Re: JBoss 5.1 + getRealPath()
          idyoshin

          Hello Robert,


          Why you want to store your files in the WEB-APP directory ? That would lead to storage problems in case of upgrade :). Why don't you simply define a storage component with configurable base directory for your application in components.xml And use that instead of web-app directory.



          Kind regards,


          Ilya Dyoshin

          • 2. Re: JBoss 5.1 + getRealPath()
            ranophoenix

            Hi Ilya,


            Absolutely! Actually it's more a curiosity than a necessity. :)



            Do you have an example of this storage component?


            How could I make it accessible to users (HTTP GET)? Creating a Servlet or is there an approach more Seam-like to do this?


            Thanks,


            Robert

            • 3. Re: JBoss 5.1 + getRealPath()
              idyoshin

              hi Robert,


              for storing it's possible to do something similar to this:


              public class FileStoreService implements Serializable{
                   
                   /**
                    * 
                    */
                   private static final long serialVersionUID = 1L;
                   private String baseFilePath;
              
                   public String getBaseFilePath() {
                        return baseFilePath;
                   }
              
                   public void setBaseFilePath(String baseFilePath) {
                        this.baseFilePath = baseFilePath;
                   }
                   
                  private String constructFilePath(UniqaDocumentFiles documentFile) {
                      String filepath = this.getBaseFilePath();
                      filepath = filepath + "/" + documentFile.getDocument().getId();
                      (new File(filepath)).mkdirs();
                      filepath = filepath + "/" + documentFile.getId();
                      return filepath;
                  }
              
                  public String save(byte[] fileContent, UniqaDocumentFiles documentFile) throws IOException {
                       
                       String filepath = constructFilePath(documentFile);
                       documentFile.setFilePath(filepath);
                      File file = new File(filepath);
                      if (file.createNewFile()) {
                          FileOutputStream fstream = new FileOutputStream(file);
                          fstream.write(fileContent);
                          fstream.flush();
                          fstream.close();
                      } else {
                          return null;
                      }
              
                      return filepath;
                  }
                  
                  public byte[] getFileContent(UniqaDocumentFiles documentFile) throws IOException {
                       
                       File file = new File(constructFilePath(documentFile));
                      InputStream is = new FileInputStream(file);
                      byte[] buffer = new byte[(int) file.length()];
                      is.read(buffer);
                       return buffer;
                  }
                  
                  public File getFile(UniqaDocumentFiles documentFile) throws IOException {
                       return new File(constructFilePath(documentFile));
                  }
                  
                  public Boolean deleteFile(UniqaDocumentFiles documentFile) {
                       try {
                            return (new File(constructFilePath(documentFile))).delete();
                       } catch (Exception e) {
                            return false;
                       }
                  }
              }



              which than could be easily created via :


                   <component name="fileStoreService" auto-create="true"
                        class="com.uniqa.session.FileStoreService" scope="APPLICATION">
                        <property name="baseFilePath">/path/to/my/storage</property>
                   </component>
              



              in the components.xml



              than you can use it to save files, and later persist into database the information about the saved file (that's the UniqaDocumentFiles object in my case).



              For downloading it depends on security. you can always create something like this :



              @Name("documentFileDownloader")
              @Scope(ScopeType.APPLICATION)
              @BypassInterceptors
              public class DocumentFileDownloader extends AbstractResource  {
                   
                   /**
                    * 
                    */
                   private static final long serialVersionUID = 1L;
              
                   
                   @Logger
                   Log logger;
                   
                   public String getResourcePath() {
                      return "/download";
                  }
              
                  public void getResource(final HttpServletRequest request, final HttpServletResponse response)
                          throws ServletException, IOException {
                        new ContextualHttpServletRequest(request) {
                          public void process() throws IOException, ServletException {
                               try {
                               String attachedFileId = request.getParameter("attachmentId");
                               
                               if (attachedFileId == null) {
                                    response.setStatus(404);
                                   response.flushBuffer();
                                   return;
                               }
                               
                               EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");
                               UniqaDocumentFiles file = entityManager.find(UniqaDocumentFiles.class, attachedFileId);
                               
                               if (file == null) {
                                    response.setStatus(404);
                                   response.flushBuffer();
                                   return;
                               }
                               
                               FileStoreService fileStoreService = (FileStoreService) Component.getInstance("fileStoreService");
                               
                                 String currentFileType = file.getFileType();
                                 byte[] currentFileContent = fileStoreService.getFileContent(file);
                                 String currentFileName = file.getRemoteFileName();
                               
                              response.setContentType(currentFileType);
                              response.addHeader("Content-disposition", "attachment; filename=\""+currentFileName+"\"");
                              response.addHeader("Cache-Control", "no-cache");
                              response.setStatus(200);
                             
                              response.flushBuffer();
                              ServletOutputStream out = response.getOutputStream();
                              out.write(currentFileContent);
                              response.flushBuffer();
                             
                              out.close();
                               } catch (Exception e) {
                                    e.printStackTrace();
                               }
                          }
                      }.run();
              
                  }
              
              }



              Hope this give you a good start.


              Alternatively you can always store your files to the nginx or apache webroot - and simply provide users with URLS to those servers.



              Kind regards,


              Ilya Dyoshin

              • 4. Re: JBoss 5.1 + getRealPath()
                ranophoenix

                Ilya,


                Thank you very much!


                I'll study your solution. ;)



                Regards,


                Robert