Upload an image to a Path set in web.xml using pri

2019-04-16 23:45发布

I have consulted most of the posts here on stackoverflow on uploading images in primefaces. With this help, I have been able to upload an image to a destination path statically specified in code as shown in this post. save image file in specific directory jsf primefaces project. This works fine.

However, I wish to upload an Image to a desitnation path specified in web.xml. This is because I want the path to be configurable even after the application is deployed. When I use ServletContext#getRealpath(), the return path is with in the myProject folder, but I want the destination path to be completely external to the project since I have found it as the best way. e.g E:/myUploads

This is my web.xml

<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    <init-param>
        <param-name>thresholdSize</param-name>
        <param-value>51200</param-value>
    </init-param>
    <init-param>
        <param-name>uploadDirectory</param-name>
        <param-value>E:/myUploads</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

This is my bean.

public void handleFileUpload(FileUploadEvent event){
  //get uploaded file from the event
  UploadedFile uploadedFile = (UploadedFile) event.getFile();
  //create an InputStream from the uploaded file
  InputStream inputStr = null;
  try 
 {
    inputStr = uploadedFile.getInputstream();
    } catch (IOException e) {
        //log error
    }

  ServletContext servletContext =      (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();
  String uploadPath = servletContext.getRealPath("");
  File destFile = new File(uploadPath);

//use org.apache.commons.io.FileUtils to copy the File
    try {
        FileUtils.copyInputStreamToFile(inputStr, destFile);
    } catch (IOException e) {
        //log error
    }
    FacesMessage msg = new FacesMessage(event.getFile().getFileName() + " is uploaded.");
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

My desire is to save the Uploaded Image in E:/myUploads without having to say:

String destPath = "E:\\myUploads\\" + uploadedFile.getFileName(); 

I will be glad if you also show me how to display the uploaded images using

<p:graphicImage

2条回答
等我变得足够好
2楼-- · 2019-04-17 00:07

BalusC Answer has helped me a great deal.. Thanks again BalusC. If any one is interested in the final code, here it is...

Am using tools Netbeans 7.4, Primefaces 4.0, GlassFish 3.1.2

This is my upload Form.

<h:form  enctype="multipart/form-data">  
        <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}" mode="advanced" dragDropSupport="false"  
                      update="messages" sizeLimit="100000" fileLimit="3" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />  
        <p:messages id="messages" showDetail="true"/>  

    </h:form>  

I have the Apache Commons libraries in my lib

commons-io-2.4.jar  (http://commons.apache.org/io)
commons-fileupload-1.3.jar  (http://commons.apache.org/fileupload)

I have this in my web.xml

<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    <init-param>
        <param-name>thresholdSize</param-name>
        <param-value>51200</param-value>
    </init-param>
</filter>

<context-param>
    <param-name>uploadDirectory</param-name>
    <param-value>E:/myUploads</param-value>
</context-param>

<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

This is my FileUploadController

@ManagedBean(name = "fileUploadController")
@ViewScoped
public class FileUploadController {

public void handleFileUpload(FileUploadEvent event) {
    //get uploaded file from the event
    UploadedFile uploadedFile = (UploadedFile) event.getFile();
    //create an InputStream from the uploaded file
    InputStream inputStr = null;
    try {
        inputStr = uploadedFile.getInputstream();
    } catch (IOException e) {
        //log error
    }

    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    String directory = externalContext.getInitParameter("uploadDirectory");
    String filename = FilenameUtils.getName(uploadedFile.getFileName());
    File destFile = new File(directory, filename);

    //use org.apache.commons.io.FileUtils to copy the File
    try {
        FileUtils.copyInputStreamToFile(inputStr, destFile);
    } catch (IOException e) {
        //log error
    }
    FacesMessage msg = new FacesMessage(event.getFile().getFileName() + " is uploaded.");
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

}

This works well. All the best.

查看更多
闹够了就滚
3楼-- · 2019-04-17 00:11

The uploadDirectory initialization parameter represents the temporary file storage location for the case the uploaded file is larger than the configured threshold size. The configured directory is not intented as a permanent file storage location. It will be auto-cleaned at moments beyond your control.

Get rid of it altogether and create an independent context parameter instead.

<context-param>
    <param-name>uploadDirectory</param-name>
    <param-value>E:/myUploads</param-value>
</context-param>

Then you can use

String directory = externalContext.getInitParameter("uploadDirectory"); 
String filename = FilenameUtils.getName(uploadedFile.getFileName());
File file = new File(directory, filename);
// ...

You should indeed never never use getRealPath(). You've by the way another potential problem when another user happens to upload a file with coincidentally the same filename. You can use File#createTempFile() to autogenerate unique filenames with a fixed prefix/suffix. See also How to save uploaded file in JSF.

查看更多
登录 后发表回答