how to get a file's full path using <p:fileUpload> - jsf

i'm having a problem to get the fullPath of a file which i upload using primefaces component . This is my code:
<h:form prependId="false" enctype="multipart/form-data">
<p:fileUpload update="#form" mode="advanced" auto="true"
fileUploadListener="#{myBean.myFileUpload}"/>
<h:outputText value="#{myBean.fileName}"/>
</h:form>
#ManagedBean
#SessionScoped
public class MyBean {
private String fileName;
public void myFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
fileName = event.getFile().getFileName();
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
i only get the file's name but what i really want to get is the full path.
i already try this but it doesn't show anything.
fileName = FilenameUtils.getFullPath(event.getFile().getFileName());

What would you expect as fullPath of an uploaded file? The Browser sent you some bytes, they are in the memory of the servletcontainer and nowhere stored. There is no fullPath like /var/tmp/myfile.txt.

Try this:
String fileName = event.getFile().getFileName();
ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
String newFileName = servletContext.getRealPath("") + File.separator + "upload" + File.separator+ fileName;
where "upload" must be replaced by name given in web.xml configuration for prime faces:
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
<init-param>
<param-name>uploadDirectory</param-name>
<param-value>/upload</param-value>
</init-param>
</filter>

Related

JSF Primefaces pass parameter to fileupload

JSF 2.2 - Primefaces 4.0 - JBoss Wildfly
Hi, I am trying to pass a parameter value to the file upload handler.
I tried a few suggestions I found, but can't get it to work.
I stepped a few steps back
I need the #{fileUploadController.newItemId} in the controller
When going to the file update page it is done with i.e. this URL
/fileUpload.jsf?newItemId=10
I tried what it mentioned in
How to send parameter to fileUploadListener in PrimeFaces fileUpload
and
Passing value to the backing bean with PrimeFaces file upload
fileUpload.xhtml
<f:metadata>
<f:viewParam name="newItemId"
value="#{fileUploadController.newItemId}" />
<f:viewAction action="#{fileUploadController.loadData()}" />
</f:metadata>
<h:form id="item" enctype="multipart/form-data">
<p:messages id="messages" />
<p:panelGrid styleClass="panelGridCenter">
<p:row>
<p:column>
<p:fileUpload
fileUploadListener="#{fileUploadController.handleFileUpload}"
validator="#{fileUploadController.validateFile}" mode="advanced"
dragDropSupport="false" update="messages" sizeLimit="1000000"
fileLimit="100" allowTypes="/(\.|\/)(gif|jpe?g|png)$/">
</p:fileUpload>
</p:column>
</p:row>
</p:panelGrid>
</h:form>
FileUploadController.java
public void handleFileUpload(FileUploadEvent event) {
try {
// Need item id here :)
UploadedFile file = event.getFile();
InputStream inputStream = file.getInputstream();
FileOutputStream outputStream = new FileOutputStream(file.getFileName());
byte[] buffer = new byte[4096];
int bytesRead = 0;
while (true) {
bytesRead = inputStream.read(buffer);
if (bytesRead > 0) {
outputStream.write(buffer, 0, bytesRead);
} else {
break;
}
}
outputStream.close();
inputStream.close();
Long imageId = serviceSLSB.saveImage(itemId, file, buffer);
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded and saved with id." + imageId);
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (Exception e) {
String errorMessage = getRootErrorMessage(e);
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Saving unsuccessful");
facesContext.addMessage(null, m);
}
}
public void loadData() {
if (newItemId == null) {
String message = "Bad request. Please use a link from within the system.";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
return;
} else {
String message = "Your are adding images to item with id : " + newItemId;
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, null));
return;
}
}
I just found that my controller was only request scoped, after changing it to
#ViewScoped
#Named
public class FileUploadController implements Serializable
I of cause still have the item id, and can now add images to that item.
Thanks for the comments guys

PrimeFaces uploadFile is not working

I'm using PrimeFaces <p:fileUpload>. It does not invoke the listener method. If I add the FileUploadFilter, then I get an exception.
View:
<h:form enctype="multipart/form-data">
<p:fileUpload mode="advanced"
fileUploadListener="#{fileUploadController.upload()}"
allowTypes="/(\.|\/)(gif|jpg|jpeg|gif|png|PNG|GIF|JPG|JPEG)$/"
auto="false" />
</h:form>
Bean:
public class fileUploadController {
private String destination = "c:\test";
public void upload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Success! ", event.getFile()
.getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
// Do what you want with the file
try {
copyFile(event.getFile().getFileName(), event.getFile()
.getInputstream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void copyFile(String fileName, InputStream in) {
try {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(destination
+ fileName));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
System.out.println("New file created!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
web.xml
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
fileUploadListener="#{fileUploadController.upload()}" is problem here. I reproduced that and I also got an exception Method not found:
You should define fileUploadListener whithout parentheses. When you have added parentheses, expected method in your bean is upload() and not upload(FileUploadEvent event)

Where is the p:fileUpload uploaded file saved and how do I change it?

I use the simple File upload of Primefaces in development with Netbeans. My test example is similar to to the Primefaces manual.
My question: where does the file get uploaded on my local computer? How can I change the path for it? Thx!
The jsf file:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Page test</title>
</h:head>
<h:body>
Hello! My first JSF generated page!
<h:form enctype="multipart/form-data">
<p:fileUpload value="#{fileBean.file}" mode="simple" />
<p:commandButton value="Submit" ajax="false"/>
</h:form>
</h:body>
</html>
and the managed bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
#ManagedBean
#RequestScoped
public class FileBean {
private UploadedFile file;
public FileBean() {
}
public UploadedFile getFile() {
return file;
}
public void setFile(UploadedFile file) {
this.file = file;
}
}
It's by default saved in either the servlet container's memory or the temp folder, depending on the file size and the Apache Commons FileUpload configuration (see also "Filter Configuration" section of the <p:fileUpload> chapter in PrimeFaces User's Guide).
You shouldn't worry about this at all. The servlet container and PrimeFaces know exactly what they do. You should in the command button's action method actually be saving the uploaded file contents to the location where you need it to be. You can get the uploaded file contents as an InputStream by UploadedFile#getInputStream() or as a byte[] by UploadedFile#getContents() (getting a byte[] is potentially memory expensive in case of large files, you know, each byte eats one byte of JVM's memory, so don't do that in case of large files).
E.g.
<p:commandButton value="Submit" action="#{fileBean.save}" ajax="false"/>
with
private UploadedFile uploadedFile;
public void save() throws IOException {
String filename = FilenameUtils.getName(uploadedFile.getFileName());
InputStream input = uploadedFile.getInputStream();
OutputStream output = new FileOutputStream(new File("/path/to/uploads", filename));
try {
IOUtils.copy(input, output);
} finally {
IOUtils.closeQuietly(input);
IOUtils.closeQuietly(output);
}
}
(FilenameUtils and IOUtils are from Commons IO which you should anyway already have installed in order to get <p:fileUpload> to work)
To generate unique file names, you may find File#createTempFile() facility helpful.
String filename = FilenameUtils.getName(uploadedFile.getFileName());
String basename = FilenameUtils.getBaseName(filename) + "_";
String extension = "." + FilenameUtils.getExtension(filename);
File file = File.createTempFile(basename, extension, "/path/to/uploads");
FileOutputStream output = new FileOutputStream(file);
// ...
I used simple mode, GlassFish 4.0 and PrimeFaces 4.0
Backing Bean
private UploadedFile file;
private String destination="C:\\temp\\";
public void upload() {
System.out.println("uploading");
if(file != null) {
System.out.println("the file is" +file);
FacesMessage msg = new FacesMessage("Succesful" + file.getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
try {
copyFile(file.getFileName(), file.getInputstream());
}
catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("uploaf finished");
}
public void copyFile(String fileName, InputStream in) {
try {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(destination + fileName));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
System.out.println("New file created!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
JSF page
<p:commandButton value="Submit" ajax="false" actionListener="#{staffController.upload}"/>

p:fileUpload method not fired

I have a form with a p:fileUpload, and when I submit the form, all methods are not fired
This is my xhtml :
<h:form enctype="multipart/form-data">
<p:messages id="messages" showDetail="true"/>
<p:fileUpload value="#{uploadBean.file}" mode="simple" id="fileUploadId"/>
<p:commandButton value="Envoyer ce fichier" process="#form" update="messages fileUploadId" actionListener="#{uploadBean.upload}"/>
</h:form>
my bean :
public void setFile(final UploadedFile file)
{
System.out.println("Dans le setFile");
this.file = file;
}
public void upload()
{
System.out.println("Dans le upload");
System.out.println("Fichier : " + file.getFileName());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
my web.xml :
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>
org.primefaces.webapp.filter.FileUploadFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
In the trace, I have just :
Infos: Dans le upload
Grave: Réception de «java.lang.NullPointerException» lors de l’invocation du listener d’action «#{uploadBean.upload}» du composant «j_idt11»
Grave: java.lang.NullPointerException
The method setFile() is not call...
Thanks
edit :
All the code of my bean :
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
#ManagedBean
#ViewScoped
public class UploadBean implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 556636819990963651L;
private UploadedFile file;
public UploadedFile getFile()
{
System.out.println("Dans le getFile");
return file;
}
public void setFile(final UploadedFile file)
{
System.out.println("Dans le setFile");
this.file = file;
}
public void upload()
{
System.out.println("Dans le upload");
// System.out.println("Fichier : " + file.getFileName());
FacesMessage msg;
if (file == null)
{
msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Raté ! ", "Le fichier vaut null.");
System.out.println("la variable file : null");
}
else
{
msg = new FacesMessage("Ouép ! ", file.getFileName() + " is uploaded.");
System.out.println("Le nom du fichier uploader est : " + file.getFileName());
}
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
From what you provided, I think you have done correctly so far. However, there are still 2 things you need to take care of:
You need to download common-io & common-fileupload and import the .jar file into your Library folder.
You also need to make sure that there are no other filters in web.xml or any classes that are annotated with #WebFilter which may read the HttpServletRequest#getInputStream() before PrimeFaces's filter, because it can be read only once.
You are using prettyfaces too? Then try it (set dispatcher):
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
I had a similar issue, the form was not submitted and the setters methods were never called, add
<f:ajax event="change"/>
inside the component what u want to submit. also
"immediate=true"
on the component itself. Thought might be helpful to others..

Navigation to call action for bean class

I am using JSF 2.0 and PrimeFaces 3.0. I have uploaded the images and have to crop the image. The images are uploaded and successfully displayed in the upload pages.
When I select the images and click the crop button the corresponding crop bean is not called. If I don't select the image and click the crop button the corresponding crop bean class is called but a NullPointerException occurred. What is the problem?
The Facelet view is:
<h:form>
<p:panel header="FILE UPLOAD WITH CROPPER" style="width:900px; margin: 0 auto; margin-top:0px">
<p:fileUpload fileUploadListener="#{photoUploadAction.handleImageUpload}"
mode="advanced"
update="getImageId,messages" auto="false"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
<p:growl id="messages" showDetail="true"/>
<p:growl id="uploadMessages" showSummary="true" showDetail="true"/>
<h:panelGrid columns="2" >
<p:imageCropper value="#{photoUploadAction.croppedImage}" id="getImageId"
image="images/#{photoUploadVO.imageName}"/>
</h:panelGrid>
<p:commandButton value="Crop" update="getImageId" action="#{imageCropperBean.crop}" />
</p:panel>
</h:form>
BACKING BEAN for ImageCropper:
#ManagedBean(name="imageCrop")
#RequestScoped
public class ImageCropperBean {
private CroppedImage croppedImage;
private String newFileName;
private String imageName;
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
System.out.println("TEH IMAGE NAME ===="+imageName);
this.imageName = imageName;
}
public String getNewFileName() {
return newFileName;
}
public void setNewFileName(String newFileName) {
System.out.println("AAAAAAAAAAAAAA"+this.newFileName);
this.newFileName = newFileName;
}
public CroppedImage getCroppedImage() {
return croppedImage;
}
public void setCroppedImage(CroppedImage croppedImage) {
System.out.println("cRRRRRRRRRRRRR"+croppedImage);
this.croppedImage = croppedImage;
}
public ImageCropperBean(){
}
public String crop() {
System.out.println("WELCOMEMMMMMMMMMMMMMM");
FacesContext context = FacesContext.getCurrentInstance();
ImageCropperBean imageCropperBean = (ImageCropperBean) context.getApplication().evaluateExpressionGet(context, "#{imageCropperBean}", ImageCropperBean.class);
ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
newFileName = servletContext.getRealPath("") + File.separator + "cropImage" + File.separator+ "croppedImage.jpg";
System.out.println("FILE NAME NAME NAME NAME "+newFileName);
String file = new File(newFileName).getName();
System.out.println("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"+file);
imageCropperBean.setImageName(file);
File fileFolder = new File("e:/Mecherie_project/image_web/WebContent/cropImages",file);
System.out.println("FILE ANE"+file);
// String target=null;
FileImageOutputStream imageOutput;
try {
imageOutput = new FileImageOutputStream(fileFolder);
System.out.println("HHHHHHHHHH=="+imageOutput);
imageOutput.write(croppedImage.getBytes(), 0, croppedImage.getBytes().length);
imageOutput.close();
FacesMessage msg = new FacesMessage("Succesful", file
+ " is cropped.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (FileNotFoundException e) {
FacesMessage error = new FacesMessage(FacesMessage.SEVERITY_ERROR,
"The files were not Cropped!", "");
FacesContext.getCurrentInstance().addMessage(null, error);
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage(FacesMessage.SEVERITY_ERROR,
"The files were not Cropped!", "");
FacesContext.getCurrentInstance().addMessage(null, error);
}
// System.out.println("ghfhgfghgh"+target);
return "success";
}
}

Resources