FileDownload and FileUpload JSF Primefaces not working - jsf

I'm using PrimeFaces 3.1.2, NetBeans 7.2, JSF 2.1 and GlassFish 3.1.2.
I'm using the actual code I got from http://www.primefaces.org/showcase/ui/fileUploadAuto.jsf
and http://www.primefaces.org/showcase/ui/fileDownload.jsf.
When I run the file upload code, it doesn't work at all. The file doesn't get uploaded and no success message is shown. But if the file size exceeds the size mentioned, it is showing a message that the file size is too large.
Here is my view:
<?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:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form enctype="multipart/form-data">
<p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}"
mode="advanced"
update="messages"
auto="true"
sizeLimit="100000"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
<p:growl id="messages" showDetail="true"/>
</h:form>
</h:body>
</html>
Here is my backing bean:
package com;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.FileUploadEvent;
#ManagedBean
#SessionScoped
public class FileUploadController {
public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
Its basically the same code in the PrimeFaces showcase page.
Similarly with file download code; when I click on download nothing happens. A pop up opens and closes before I could even notice it. I have the image file in place as mentioned in the get resource stream (for the download part), but I don't know what's the problem. The code is also basically the same as in the PrimeFaces showcase page.
I don't see any logs or errors under Glassfish in Netbeans. I also don't know how to enable logging if necessary.

The first thing you need is add some libraries to your application. As a matter of fact, PrimeFaces file upload relies on Apache commons-file-upload and commons-io libraries. So dowload them and add them to your WEB-INF/lib path:
you can download it from following link.
http://commons.apache.org/io/
http://commons.apache.org/fileupload/
in addition you have to configure it into 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>C:\etc</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
Also If you want to set programmatically change the destination of your uploaded files have a look:
PrimeFaces FileUpload File Saving Destination

To be able use the bean from the xhtml, you need to annotate your controller as a #ManagedBean and set some scope. Preferably #ViewScoped or #RequestScoped in this case.
example:
#ManagedBean
#ViewScoped
public class FileUploadController {
public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
Learn more about how jsf managed beans works here: http://www.mkyong.com/jsf2/configure-managed-beans-in-jsf-2-0/

One thing that I have noticed is that if you don't put inside the tag "allowTypes" a regular expression correctly, the "fileupload" element does not trigger the action, giving the impression that the action is unreachable.
I know that this is not your problem right now, but I think it is important to share this information.

Related

Primefaces fileUpload is not called

I am using primefaces 5.0 and jsf 2.2 and I keep getting a NullPointer error.
.xhtml file:
<h:form enctype="multipart/form-data">
<p:fileUpload fileUploadListener="#{mBKnjiga.uploadSlike}" mode="advanced" allowTypes="*.jpg;*.png;*.gif;" />
Bean:
byte[] image;
...
public void uploadSlike(FileUploadEvent event) throws IOException {
image = IOUtils.toByteArray(event.getFile().getInputstream());
}
web.xhtml:
<filter>
<filter-name>primeFacesFileUploadFilter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>primeFacesFileUploadFilter</filter-name>
<servlet-name>FacesServlet</servlet-name>
</filter-mapping>
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>auto</param-value>
</context-param>
I have added the jars for commons-io and commons-fileupload just in case. Also I have tried to upload the picture using the mode="simple" the way it was explained in their showcase but it didn't work. I also tried it without the commons fileupload.
I think your allowTypes value is breaking the component. allowTypes expects a regular expression. Try allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
The problem was with the primefaces version. Primefaces 6.1 works just fine.

JSF Memory leak: bean not destroyed on refresh / redirect on same page

I use JSF viewscope for my managedbean.
I call the managed bean in a html view.
When the page is refresh, there is a new managed bean allowed and the old one stay in the memory.
If I refresh and refresh and refresh... I have got a huge number of the managed beans in the memory.
I try to run garbage collector, nothing append.
The managed beans stay until the session expired. At the end of session, by user action or timeout, the managed bean are freed.
I only have this problem when I stay on the same page (refresh on the browser -F5- or redirection link without JSP tag or java code redirection).
When I change page, there is only one managed bean freed (the last one). The others stay in the memory.
It seme to work with JSP tag, the managed bean are freed after the redirection.
Second Bug :
Some time I arrived in strange case :
I have some managed bean not freed in memory, I use JSP tag redirect (may 3/4 times) and the system do Predestroy / PostConstruct / Predestroy...
And after that every redirection do PostConstruct / Predestroy for not JSP tag or java redirection, Predestroy / PostConstruct / Predestroy for JSP tag.
In the memory a managed bean not freed is freed after that.
I realy don't know what is realy the case reproduce this, but it do multiple time.
Do somebody have some solution for this problems ?
I see a post look like problem here and I report a bug on java.net
Configuration :
Java EE 7 / glassfish 4
AViewscope.java :
package com.btm.viewscopetest;
import java.io.IOException;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
#ManagedBean
#ViewScoped
public class AViewscope implements Serializable {
#PostConstruct
public void postConstruct() {
System.out.println("PostConstruct");
}
#PreDestroy
public void preDestroy() {
System.out.println("PreDestroy");
}
public AViewscope() {
}
public String getSomething() {
return "Something";
}
public void redirect() throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.redirect("apage.xhtml");
}
}
apage.xhtml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<head>
<title>A page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<h:form>
<h:outputText value="Get something: #{aViewscope.something}" />
<br/>
<br/>
<h:commandButton value="Stay on this page with java " actionListener="#{aViewscope.redirect}"/>
<br/>
<h:commandButton value="Stay on this page with direct link" action="apage" />
<br/>
<h:commandButton value="Go to another page" action="anotherPage"/>
<br/>
<h:commandLink value="Stay on this page with direct link h tag " action="apage.xhtml" />
Stay on this page with direct link a tag
</h:form>
</body>
</html>
anotherPage.xhtml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<head>
<title>Another Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<h:form>
<h:commandButton value="Go to another page" action="apage"/>
</h:form>
</body>
</html>
web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
</web-app>
I have got a huge number of the managed beans in the memory.
I try to run garbage collector, nothing append
This is not a bug, it's intentional. JSF maintains a certain number of beans in the memory, if your javax.faces.STATE_SAVING_METHOD is set to server in the web.xml. The client will now always submit a javax.faces.ViewState (id), allowing the server to identify the proper beans to load.
You can limit the amount of views stored per session, by setting the context-param com.sun.faces.numberOfViewsInSession to a number that matches your needs.
But be aware that if you choose 1, and the user use backwards navigation he will encounter ViewExpired exceptions if the bean has been removed.
Another option to decrease memory load would be to handle the view-storage over to the client, by setting javax.faces.STATE_SAVING_METHOD to client. However this will lead to increased network traffic, because now the client does not only need to have a javax.faces.ViewState to track - but the whole view itself. I'm not one hundred percent sure how exactly the client-option works, but to me it feels dangerous to let a client keep track of the "View" rather than just the identifier.

JSF File Upload in WebSphere 8.5

I'm working on a JSF 2.2 application where we need to upload some .csv files via the web page. It works fine when we deploy to Tomcat, but for some reason it isn't working with WebSphere. Here is the example below that I am trying to get working:
index.html
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/WEB-INF/templates/template.xhtml">
<ui:define name="header">
Header
</ui:define>
<ui:define name="content">
<h:messages></h:messages>
<h:form enctype="multipart/form-data">
<h:inputFile id="file" value="#{fileUploadManagedBean.file}">
</h:inputFile>
<h:commandButton value="Upload"
action="#{fileUploadManagedBean.upload()}" />
</h:form>
<h:outputLabel>JSF Implementation: #{fileUploadManagedBean.jsfImplementation}</h:outputLabel>
<br />
<h:outputLabel>JSF Version: #{fileUploadManagedBean.jsfVersion}</h:outputLabel>
</ui:define>
<ui:define name="footer">
Footer
</ui:define>
</ui:composition>
</html>
And here is my backing bean, FileUploadManagedBean.java
package com.mycomp.test;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.Part;
import org.apache.log4j.Logger;
#ManagedBean
#SessionScoped
public class FileUploadManagedBean {
public static Logger logger = Logger.getLogger(FileUploadManagedBean.class);
private Part file; // The file being uploaded
public String upload() {
logger.info("Initiating bulk upload...");
logger.debug("content-type: "+ file.getContentType());
logger.debug("filename: "+ file.getName());
logger.debug("size: "+ file.getSize());
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Uploaded", "Uploaded"));
return null;
}
public Part getFile() {
return file;
}
public void setFile(Part file) {
this.file = file;
}
public String getJsfImplementation() {
return FacesContext.class.getPackage().getImplementationTitle();
}
public String getJsfVersion() {
return FacesContext.class.getPackage().getImplementationVersion();
}
}
When I open up the page, it prints out "Mojarra" and "JSF 2.2", so I know that the backing bean is being accessed and that JSF 2.2 is being utilized, but when I click "upload", Java is never called and there are no entries in the WebSphere log; the page just refreshes. When I look at the HTTP packets being sent (from the browser side), I see the file being sent in the POST request, and then I get a 200 OK response.
Any ideas?
After days of debugging and trying alternatives, we discovered that the issue is that WebSphere 8.5.5 requires any servlet trying to read multipart data to either add a multipart-config element to its definition in the web.xml file, or to use the #MultipartConfig annotation. It would appear that the JSF 2.2 servlet was not implementing this correctly, since once we added the multipart-config element to our web.xml file, everything worked fine on WebSphere.
I'm not exactly sure why our code initially worked on Tomcat, but not in Websphere; I suspect that either the JSF 2.2 build we are using is faulty, or Tomcat is just a little more forgiving and didn't require us to be as explicit.
The Primefaces uses two file upload decoder for uploading content of p:fileupload
1- NativeFileUploadDecoder
2- CommonsFileUploadDecoder
NativeFileUploadDecoder is the default upload decoder and it requires servlet container 3.0 so if your servlet container is less than 3 then it will not work with you. also some application servers make a restriction on using multi-part content
so if you have a problem with the native upload decoder for any reason you have to use the other decoder which is "CommonsFileUploadDecoder"
CommonsFileUploadDecoder depends on Apache common lib so you have to put the commons-fileupload and commons-io jars in your class-path the version depends on your primefaces version but 1.3 and 2.2 respectively works for me.
to use CommonsFileUploadDecoder you have to use filter
<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>
wait the filter only will not work because inside the filter it checks about the uploader if its not provided and it detect at least JSF 2.2 so it will bypass the request to the default decoder "Native" and then it will not work for your also
to force the filter to use the common decoder you have to put the following context param in your web.xml
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value>
</context-param>

#SessionScoped bean injected as #ManagedProperty of a #ViewScoped acts like #RequestScoped in MyFaces, works fine in Mojarra

Here is my simple example:
Index.xhtml in root:
<?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">
<h:head>
<title>Title</title>
</h:head>
<h:body>
<h:form>
<h:inputText value="#{index.variable}"></h:inputText>
<h:commandButton action="#{index.submit()}" type="submit"></h:commandButton>
</h:form>
</h:body>
</html>
Its ManagedBean:
import java.io.IOException;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
#ManagedBean
#ViewScoped
public class Index implements Serializable {
#ManagedProperty("#{sessionBean}")
private SessionBean sessionBean; /*getter&setter*/
private String variable; /*getter&setter*/
public void submit() {
sessionBean.setAsd(variable);
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
try {
context.redirect("next");
} catch (IOException ex) {
}
}
}
/next/index.xhtml:
<?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">
<h:head>
<title>Check variable</title>
</h:head>
<h:body>
#{sessionBean.asd}
</h:body>
</html>
SessionBean.java:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class SessionBean implements Serializable {
private String asd;
public String getAsd() {
return asd;
}
public void setAsd(String asd) {
this.asd = asd;
}
}
If I use mojarra implementation everything works as expected: after form submitting, user gets redirected to root/ and see the value that was printed in the form of index.xhtml.
But if I use myfaces, asd becomes null right after existing form gets submitted. SessionScoped bean acts like RequestScoped
Why?
here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
<!--listener-class>com.sun.faces.config.ConfigureListener</listener-class-->
</listener>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
Server: Apache Tomcat 7.0.34
UPDATE: it works if we change the ViewScoped annotation of Index.java bean to RequestScoped or SessionScoped. But why?
I currently have a JSF 2.1 project written with the help of Mojarra. Just for experimenting, I changed the implementation to MyFaces and ran the application only to see issues similar to yours (all my injected #ManagedProperty variables end up null after a POST submit). I switched back to Mojarra and the app runs fine. So, basically something is different in the MyFaces implementation.
A bit of googling led me to this unresolved issue - MYFACES-3656. Here's an excerpt from the issue reporter on how to fix the issue:
If you set the org.apache.myfaces.SERIALIZE_STATE_IN_SESSION to false
and redeploy the application then everything works as expected.
How does this help? The answer is in the comments section:
I think the behavior described is expected (different to say that the
behavior described is desired or intentionally done in that way).
What's happening here is in MyFaces serialization is set to true by
default (some old lines from JSF 1.0 spec says so, even if RI does not
implement it in this way). In JSF 2.2 spec, SERIALIZE_STATE_IN_SESSION
param will be standardized and set to false by default.
Serialization causes that all beans under view scope are in fact
"recreated". If the param is set to false, the beans are stored into
session and on further requests are used, looking like everything is
ok, but that fact is not true because in a cluster configuration the
same application will fail.
Only the first time the view scope bean is created, the references
from managed-property takes effect, but if the bean is
serialized/deserialized, the references are not restored back, because
on the serialization step, even the application and session scope
beans are serialized too.
.....
How to solve it? I haven't found a decent solution to this issue. One
could think on just restore the view scope bean and reapply
#ManagedProperty annotations or entries found in faces-config.xml, but
the problem is the view scope bean still is storing information that
shouldn't be there from start (only marking the fields as transient
will do the trick). It is possible define an special mode were this
hack or some variant is done, but it will be only in myfaces and it
cannot be enabled by default.
Similar issue has been reported and replied with the above explanation in this mailing-list archive
Now, since in your case you are not explicitly setting a STATE_SAVING_METHOD, it defaults to server. Consequently, SERIALIZE_STATE_IN_SESSION comes into effect and defaults to true.
I tried your code with MyFaces on Tomcat and set SERIALIZE_STATE_IN_SESSION to false and it works. However, in the event, you set the STATE_SAVING_METHOD to client, nothing will work and you'll get a view state not found error.

simple JSF commandButton not hitting the action

I have the simplest little JSF example (JSF2 with GlassFish) and I can't figure out why the command button is not hitting the action method. This is what I have ... when I click the button, nothing happens.
What am I doing wrong?
testForm.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:form>
<h:messages />
<p/>
<h:inputText />
<p/>
<h:commandButton value="test1" action="#{testController.action1}" />
</h:form>
</html>
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<managed-bean>
<managed-bean-name>testController</managed-bean-name>
<managed-bean-class>com.app.controller.TestController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
TestController.java
package com.app.controller;
public class TestController {
public String action1() {
return "testPage2";
}
}
Eureka! After rebuilding the Eclipse project from scratch I realize what I did wrong. Apache MyFaces is in the project path and the app is being deployed on GlassFish which has it's own JSF implementation. The two JSF implementations don't want to play nicely together.
What a pain. And, you know, I made this exact same mistake once before. Eclipse should warn you about this or there should be some error reported in the GlassFish log or the h:messages tag.
1)For JSF2.0, Its not required to configure managed bean in Facesconfig.xml.
2)can use #managedban annotation.
package com.app.controller;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "testController")
#SessionScoped
public class TestController {
public String action1() {
return "testPage2";
}
/** Constructor, getters and setters*/
}

Resources