JSF creates a new SessionScoped Bean for every request - jsf

My problem is that one : at every http request, a new session scoped bean is created and I don't know why.
Here is my jsf index page :
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<link type="text/css" rel="stylesheet" href="css/default.css"/>
</h:head>
<h:body>
<p:growl autoUpdate="true" showDetail="true" globalOnly="true"/>
<h:form id="f_main">
<ui:include src="#{pageBean.page}.xhtml"/>
</h:form>
</h:body>
</html>
Here is my PageBean
package web.bean.system;
import org.apache.log4j.Logger;
import web.bean.AbstractBean;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class PageBean extends AbstractBean {
private static final long serialVersionUID = -882977117976414497L;
private static final Logger LOG = Logger.getLogger(PageBean.class);
public static final String HOME = "home";
private static int IT = 0;
private String page;
public PageBean() {
LOG.debug(IT++);
this.page = HOME;
}
public String getPage() {
LOG.debug(page);
return this.page;
}
public void setPage(String page) {
LOG.debug(page);
this.page = page;
}
}
In this case, the home page is empty.
But when I take a look at the logs after refreshing a lot of time, I can see that a new bean is created for every http request.
I have verified that I realy use javax.faces.bean and not an other package but I don't know why It doesn't work...
Have you any solution for me ?

That may happen if the HTTP session is not properly maintained between the client and the server. Before all, first learn how HTTP sessions work by carefully reading the "HttpSession" section of this answer: How do servlets work? Instantiation, sessions, shared variables and multithreading.
Now, you should understand that they're by default backed by cookies. You should now also understand that if cookies are not maintained by the client or instantly destroyed by the server for some reason, then the session won't be maintained across requests.
If you're using a bit modern webbrowser with builtin web developer toolset, press F12 to show it up and open the "Net"/"Network" tab. Look in the response header for Set-Cookie and in subsequent request header for Cookie. If Cookie is absent in request header and thus the server returns a new Set-Cookie header on the response, then it means that the client does not support cookies. Or if the right Cookie header is present and the server still returns a new Set-Cookie header on every response, then it means that the server's code has somewhere a line which calls HttpSession#invalidate() on every request (perhaps a homegrown authentication filter which is written by a starter).

Related

GlassFish is creating a new JSESSIONID on every request

I have a simple page backed by a named bean. The page is also using primefaces, but I am not doing anything ajax in that page. The applications is hosted on Glassfish 5.1.
#Named("cardsView")
#RequestScoped
public class CardsViewBean implements Serializable {
...
}
This is the xhtml page. As you can see I am passing the bean to the master xhtml, not sure if it's the best practice or the source of the problem.
<ui:composition template="/fragment/master.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:ipc="http://java.sun.com/jsf/composite/component">
<ui:param name="bean" value="${cardView}" />
<ui:define name="content">
.....
</ui:define>
</ui:composition>
It is my understanding that the request scoped bean lives just for the request.
However when I look to the browser inspector I can see that each time I hit the page a new JSESSIONID is created. So I think that there is clearly something I have wrongly configured but I am not sure where to look.
In fact, there is 2 request per page.
Initial request and postback request.
first, client makes a request to get the page. it is complete request by itself.
request: http://example.com/index
response: html page.
After user hits submit button or another button or link, browser requests another page again.
request: http://example.com/login
response: another page.
In another word, Jsf or any Ui framework holds information between 2 requests for us by various techniques and methods
see this question about Initial request and postback request
and Jsf lifecycle
and primeFaces lifeCycle show case
last Point: session has timeout in jservlet and you can config it using web.xml and If this time pass, your session expires and gives you another session
Happy Coding!

JSF: Redirection [duplicate]

I have a JSF page which posts data to an external page.
The data is loaded from a JSF managed bean which generates a unique ID in the post data.
I have an issue where a user clicks on a checkout button then navigates back to the same page and presses the checkout button again. The post data has not updated. Moreover, the bean is not invoked at all. Is there anyway to force JSF to reload the page and the form data?
<form action="#{checkoutBean.externalUrl}" method="post"
id="payForm" name="payForm">
<input type="hidden" value="#{checkoutBean.uniqueID}" />
<input type="submit" value="Proceed to Checkout" />
</form>
That page is likely being loaded from browser cache. This is essentially harmless, but indeed confusing to the enduser, because s/he incorrectly thinks that it's really coming from the server. You can easily confirm this by looking at the HTTP traffic monitor in browser's web developer toolset (press F12 in Chrome/FireFox23+/IE9+ and check "Network" section).
You basically need to tell the browser to not cache (dynamic) JSF pages. This way the browser will actually request the server for the page (and hereby triggering proper creation/initialization of managed beans and so forth) instead of showing the previously requested one from its cache.
Generally, this is to be done with a simple servlet filter like follows:
#WebFilter("/app/*")
public class NoCacheFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (!request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
}
chain.doFilter(req, res);
}
// ...
}
Where /app/* is the example URL pattern on which you'd like to turn off the browser cache. You can if necessary map it on /*, *.xhtml or even on servletNames={"Faces Servlet"}.
If you happen to use JSF utility library OmniFaces, then you can use its builtin CacheControlFilter by just adding the following entry to web.xml (which demonstrates a direct mapping on FacesServlet, meaning that every dynamic JSF page won't be cached):
<filter>
<filter-name>noCache</filter-name>
<filter-class>org.omnifaces.filter.CacheControlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>noCache</filter-name>
<servlet-name>facesServlet</servlet-name>
</filter-mapping>
See also the showcase.
I found a solution that works for JSF without having to create a servlet-filter. Just put the line below to your .xhtml page.
<f:event type="preRenderView" listener="#{facesContext.externalContext.response.setHeader('Cache-Control', 'no-cache, no-store')}" />

JSF 2.0 Multiple requests generated per page

I have implemented a Filter for checking if a user is logged in or not by checking the session for a #SessionScoped bean. When I started testing it, I however, noticed that whenever I accessed one of my pages the Filter would be invoked multiple times.
I have figured out that I needed to ignore AJAX requests which reduced the number of times my filter would be invoked but the number of requests triggered each time I loaded the page was still more than one.
By trial and error, I have figured out that the requests would be generated by the following XHTML tags (both embedded in the <h:body> tag):
<h:outputStylesheet name="styles/userbar.css" target="head"/>
<o:commandScript name="updateMessages" render="custom_messages"/>
The second tag being part of OmniFaces library.
Any ideas why I get multiple requests or maybe if there is a way to ignore the requests generated by these tags?
Any help would be appreciated.
That can happen if you mapped the filter on a generic URL pattern like #WebFilter("/*"), or directly on the faces servlet like #WebFilter(servletNames="facesServlet"). The requests you're referring to are just coming from (auto-included) CSS/JS/image resources. If you track the browser's builtin HTTP traffic monitor (press F12, Network) or debug the request URI in filter, then that should have become clear quickly.
As to covering JSF resource requests, if changing the filter to listen on a more specific URL pattern like #WebFilter("/app/*") is not possible for some reason, then you'd need to add an additional check on the request URI. Given that you're using OmniFaces, you can use the Servlets utility class to check in a filter if the current request is a JSF ajax request or a JSF resource request:
#WebFilter("/*")
public class YourFilter extends HttpFilter {
#Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain) throws IOException, ServletException {
if (Servlets.isFacesAjaxRequest(request) || Servlets.isFacesResourceRequest(request)) {
chain.doFilter(request, response);
return;
}
// ...
}
}
See also:
Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same (contains a "plain vanilla" Servlet example for the case you aren't using OmniFaces)

The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available

I have one view scoped JSF managed bean. In the action listener method of <p:commandButton> in this managed bean, I'm redirecting to another page as follows.
public void register() {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
Flash flash = context.getFlash();
flash.setKeepMessages(true);
flash.put("emailId", emailId);
context.redirect(((HttpServletRequest) context.getRequest()).getContextPath()+"/page.jsf");
}
page.jsf is bound to a request scoped bean in which I'm receiving the email address stored in a flash scope as follows.
<ui:define name="metaData">
<f:metadata>
<f:viewAction action="#{requestScopedBean.init}"/>
</f:metadata>
</ui:define>
public void init() {
String emailId = (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("emailId");
System.out.println("emailId = "+emailId);
}
The email address is unavailable in the target bean. The email address in the target bean is required just to show the user who has registered to indicate that a message has been sent to that address so that the email address can be verified.
It produces the following warning on the server terminal.
WARNING: JSF1095: The response was already committed by the time we
tried to set the outgoing cookie for the flash. Any values stored to
the flash will not be available on the next request.
Why does this happen? My Mojarra version is 2.2.7

PrimeFaces CSS skin not showing in login page, also JavaScript undefined errors

I am using PrimeFaces 3.4 in my web app and for a particular page the controls are not displayed with the normal PrimeFaces skin:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>VMS login</title>
</h:head>
<h:body>
  <h:form id="loginForm">
    <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
    <p:panel header="#{msgs['login.title']}">
      <p:panelGrid id="loginPanel" columns="2">
        <h:outputText value="#{msgs['login.username']}" />
        <p:inputText id="j_username" value="#{loginFormBean.userName}" required="true"></p:inputText>
        <p:message for="j_username" ></p:message>
        <h:outputText value="#{msgs['login.password']}" />
        <p:password id="j_password" value="#{loginFormBean.password}" required="true" feedback="false"></p:password>
        <p:message for="j_password"></p:message>
        <p:commandButton action="#{loginController.loginUsingSpringAuthenticationManager}" value="#{msgs['login.button']}" update="loginForm" ajax="true"></p:commandButton>
      </p:panelGrid>
    </p:panel>
  </h:form>
</h:body>
</html>
This outputs to:
The panel should have a header and so on.
The interesting thing is that in another page where I am using a <p:layout> with different panels in the layouts they display fine with their normal PrimeFaces look-and-feel.
What am I doing wrong? Thank you
Given that it only occurs on the login page, that can happen when the authentication mechanism also kicks on requests to JSF resources like CSS/JS/image files and redirects them to the login page as well. The webbrowser would then retrieve the HTML representation of the login page instead of the concrete resources. If you have investigated the HTTP traffic in the webbrowser's developer toolset, then you should have noticed that as well.
If you're using homegrown authentication with a servlet filter, then you need to tell the filter to not redirect them to the login page, but just continue them. It are those /javax.faces.resource/* URLs (you can get that URL path as constant by ResourceHandler#RESOURCE_IDENTIFIER).
if (request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
chain.doFilter(request, response);
return;
}
// ...
Or if you're using container managed authentication, then you should add /javax.faces.resource/* to allowed URLs which should be skipped from login checks:
<security-constraint>
<web-resource-collection>
<web-resource-name>Allowed resources</web-resource-name>
<url-pattern>/javax.faces.resource/*</url-pattern>
</web-resource-collection>
<!-- No Auth Contraint! -->
</security-constraint>
See also Exclude css & image resources in web.xml Security Constraint.
Or when you're using 3rd party authentication framework like Spring Security, then you need to tell it the following way (assuming 3.1.0 or newer)
<http security="none" pattern="/javax.faces.resource/**" />
See also Spring Security 3.0.5.
Or when you're using PicketLink, see PrimeFaces based application with PicketLink does not show style in login page.

Resources