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

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.

Related

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 bean action method return string test

I tried to understand from this question the difference between returning null and "" in JSF action, but couldn't experience in real.
Below is the quote form the OP
From what I understand, when a JSF action returns "" (empty String)
the user stays on the current page but the view is refreshed. However,
when the action returns null the user still stays on the current page
but the old view is reused
I am in a confusion of understanding the difference between returning "", null and "viewid?faces-redirect=true" from a JSF Backing bean. I tried to understand the difference with a small example, but I couldn't experience the actual difference. Below are the code snippets of my example.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Jsf Questions</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jspx</param-value>
</context-param>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/jsfintroapp/*</url-pattern>
</servlet-mapping>
</web-app>
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
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_1_2.xsd">
<managed-bean>
<managed-bean-name>userLogin</managed-bean-name>
<managed-bean-class>com.srk.beans.UserLogin</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<navigation-rule>
<description>Contains list of all navigation rules here</description>
<from-view-id>/*</from-view-id>
<navigation-case>
<display-name>WELCOME</display-name>
<from-outcome>welcome</from-outcome>
<to-view-id>/geek_examples/authorized_user.jspx</to-view-id>
</navigation-case>
</faces-config>
My managed bean is a request scoped bean, as declared above.
UserLogin.java (Backing bean) code snippet
public String saveData() {
//String returnString = "";//Case 1 : works - user stays on the same page
//String returnString = null;//Case 2: works - user stays on the same page
// Case 3:
String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
LOG.debug("view id = "+ viewId);
String returnString = "?faces-redirect=true";//viewId+
LOG.debug("return string = "+ returnString);
LOG.debug("Username = "+ getName() + " password = "+ getPassword());
return returnString;
}
login.jspx
<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">
<f:view>
<head>
<title>JSF Question</title>
</head>
<body>
<h:form>
<h3>User Name and Password</h3>
<table>
<tr>
<td><h:outputLabel value="Name"/></td>
<td><h:inputText value="#{userLogin.name}"/></td>
</tr>
<tr>
<td><h:outputLabel value="Password"/></td>
<td><h:inputText value="#{userLogin.password}"/></td>
</tr>
<tr>
<td><h:commandButton value="Sign In" action="#{userLogin.saveData}"/></td>
</tr>
</table>
</h:form>
</body>
</f:view>
</html>
Libraries used in this example
I tried to access the login.jspx page, entered values in the fields of form and clicked on Sign In. I can always see the same page, no matter what I return there in my saveData() method which is not showing any difference in behavior, Can somebody throw some light with respect to this concept?
As answered in that answer, returning null or void will reuse the same JSF view, including all view scoped beans attached to it.
JSF 1.2, however, has no concept of a "view scoped bean". This was introduced in JSF 2.0. Moreover, you've a request scoped bean. It'll always be recreated on every request, regardless of how you navigate. So it's not really noticeable by looking at how the bean behaves. It's only noticeable if you manually mimic the JSF 2.0 view scope by putting an attribute in the UIViewRoot and then checking in the constructor of the request scoped bean if it's still present.
If you have used a JSF 2.x view scoped bean, you'd have noticed that it's recreated (i.e. it's (post)constructor is invoked again) when you navigate using a non-null outcome. See also a.o. How to choose the right bean scope?
And, the ?faces-redirect=true query string is also JSF 2.x specific and not recognized by JSF 1.x. In JSF 1.x, to achieve the same effect, either add <redirect/> to the <navigation-case>, or use ExternalContext#redirect().
public void saveData() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
String url = ec.getRequestContextPath() + "/login.jsf";
ec.redirect(url);
}
Which navigation approach to choose is elaborated in this related question: How to navigate in JSF? How to make URL reflect current page (and not previous one). Generally, in UX and SEO perspective, using POST for page-to-page navigation is bad practice. Always use GET for that or perform a redirect after POST.
In any case, when developing with JSF 1.x, you should not be looking at JSF 2.x targeted answers/resources. It'll only lead to confusion because many things are done differently (better!) in JSF 2.x. JSF 2.x exist more than 5 years already and JSF 1.x was EOL for nearly as long. It doesn't make sense to keep working on dead technology. Consider migrating.

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>

<h:button> not executing simple bean method

im trying to do a simple bean method, but it does not work, dont show the syso in the console of eclispe, and when i click the button, it change my url to http://localhost:8080/Projeto01/index.jsf?jftfdi=&jffi=%2Findex.xhtml
why dont work and why it change the url for this strange url ?
my msg.java(bean)
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class Msg {
public void show() {
System.out.println("Working Bean Method");
}
}
my index.xhtml
<!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"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition>
<h:head></h:head>
<h:body>
<h:form>
<h:button value="Show" action="#{msg.show()}"></h:button>
</h:form>
</h:body>
</ui:composition>
</html>
and my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>do0</display-name>
<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>*.jsf</url-pattern>
</servlet-mapping>
</web-app>
The <h:button> is a simple page-to-page navigation button. As you can see in the tag documentation, it doesn't support the action attribute at all. You're most likely confusing the <h:button> with <h:commandButton> which in turn supports that attribute.
In order to achieve your functional requirement of invoking a JSF backing bean method on press of a button, just replace <h:button> by <h:commandButton>:
<h:commandButton value="Show" action="#{msg.show()}" />
See also:
Difference between h:button and h:commandButton
As to those jftfdi and jffi query string parameters in the target URL, this is a bug in Mojarra's implementation of the new JSF 2.2 flow scope. This is fixed in Mojarra 2.2.5. Note that this is further unrelated to your concrete problem as you shouldn't be using a <h:button> in first place.
See also:
How to disable jftfdi jffi query params in JSF

FileDownload and FileUpload JSF Primefaces not working

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.

Resources