I am currently building a prototype using PrimeFaces with reference from our current production-running Java web application (jsp – servlet – java). I have a minor problem with PrimeFaces’ watermark component.
In the login.jsf there are two InputText components – “Username” and “Password”. And there are 2 Watermark components for each of the InputText.
All was fine until I added filter in the web.xml. In the filter, it is specified that if the request URL is not “login.jsf”; and anything ending with “.js.jsf” and “.js”; and anything that contains “.css”, “.png” and “.gif” to be verified if the user is logged in or not. If the user is not logged in, the filter will redirect to logout.jsf.
The logout.jsf is a simple page with a CommandLink to the login.jsf”. By clicking the link, it brings the user to the login.jsf page but, the watermark is not displayed. But if the login.jsf is accessed directly by typing it in the browser address bar then the watermark does display.
I am scratching my head as to why the watermark does not display when I clicked on a link which brings me to the login.jsf. Is there any resources which I have blocked? or am I doing the filter wrong?
The libraries I am using are PrimeFaces 3.3.1, GlassFish 3.1.2.2, Java JDK 6u32.
login.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>PROFITEDI Login</title>
<h:outputStylesheet name="styles.css" library="css" />
</h:head>
<h:body>
<h:form id="frmLogin">
<p:panel styleClass="panelLogin">
<p:messages id="messages" autoUpdate="true" />
<f:facet name="header">
<h:outputText value="Login" />
</f:facet>
<h:panelGrid columns="2" cellpadding="5">
<p:inputText id="username" value="#{loginController.username}" required="true" />
<p:watermark for="username" value="User ID" />
<p:password id="password" value="#{loginController.password}" required="true" />
<p:watermark for="password" value="Password" />
<p:outputLabel value="Remember Me" for="rememberme" />
<p:selectBooleanCheckbox id="rememberme" value="#{loginController.rememberme}" />
</h:panelGrid>
<f:facet name="footer">
<h:panelGroup>
<p:commandButton id="btnReset" type="Reset" value="Reset" />
<p:spacer width="10" />
<p:commandButton id="btnLogin" type="Submit" value="Submit"
action="#{loginController.doLogin}" />
</h:panelGroup>
</f:facet>
</p:panel>
</h:form>
</h:body>
logout.xhtml
<!DOCTYPE html>
<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>PROFITEDI - Logout</title>
</h:head>
<h:body>
<h:form id="frmLogout">
You have been logged-out. Click here to <p:commandLink value="login" type="button" action="login" /> again.
</h:form>
</h:body>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
version="3.0">
<!-- Context Param -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<!-- this is to treat empty fields as NULL instead of blank. -->
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<!-- Servlet -->
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<!-- Welcome file -->
<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
</welcome-file-list>
<!-- Session Configuration -->
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<!-- Listener -->
<listener>
<listener-class>com.qrra.PROFIT.web.SessionListener</listener-class>
</listener>
<!-- URL Filter -->
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>com.qrra.PROFIT.web.SecurityFilter</filter-class>
<init-param>
<param-name>PAGE_LOGIN</param-name>
<param-value>login.jsf</param-value>
</init-param>
<init-param>
<param-name>PAGE_LOGOUT</param-name>
<param-value>logout.jsf</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>*.jsf</url-pattern>
</filter-mapping>
SecurityFilter
package com.qrra.PROFIT.web;
import com.qrra.util.QRUtil;
import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import qrcom.webedi.ejb.AduserFacade;
import qrcom.webedi.jpa.Aduser;
/**
*
* @author Alvin Sim
*/
public class SecurityFilter extends GenericFilter {
// Actions ---------------------------------------------------------------------------------------------------------
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest;
HttpServletResponse httpServletResponse;
String pageLogin;
String pageLogout;
String requestUrl;
if (request instanceof HttpServletRequest) {
httpServletRequest = (HttpServletRequest) request;
httpServletResponse = (HttpServletResponse) response;
pageLogin = (String) httpServletRequest.getAttribute("PAGE_LOGIN");
pageLogout = (String) httpServletRequest.getAttribute("PAGE_LOGOUT");
requestUrl = (String) httpServletRequest.getRequestURI();
if (QRUtil.isStringEmpty(pageLogin)) {
pageLogin = "/login.jsf";
}
if (QRUtil.isStringEmpty(pageLogout)) {
pageLogout = "/logout.jsf";
}
// logger.debug("requested URL: {}", requestUrl);
if (requestUrl.endsWith(pageLogin) == false && requestUrl.endsWith(".js.jsf") == false
&& requestUrl.contains(".css") == false && requestUrl.contains(".gif") == false
&& requestUrl.contains(".png") == false && requestUrl.endsWith(".js") == false) {
logger.debug("URL blocked: {}", requestUrl);
if (verifyUser(httpServletRequest, httpServletResponse) == false) {
gotoLogoutPage(httpServletRequest, httpServletResponse, pageLogout);
}
}
}
chain.doFilter(request, response);
}
private void gotoLogoutPage(HttpServletRequest request, HttpServletResponse response, String pageLogout)
throws IOException, ServletException {
RequestDispatcher dispatcher = request.getSession().getServletContext().getRequestDispatcher(pageLogout);
dispatcher.forward(request, response);
}
private boolean verifyUser(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
Aduser aduser = (Aduser) request.getSession().getAttribute("aduser");
if (aduser == null || QRUtil.isStringEmpty(aduser.getUsrId()) == false
|| request.isRequestedSessionIdValid() == false) {
logger.debug("Invalid user session. Proceed to logout user {}.", (aduser == null) ? "" : aduser.getUsrId());
return false;
}
else {
return true;
}
}
// Services --------------------------------------------------------------------------------------------------------
@EJB
private AduserFacade aduserFacade;
// Constants -------------------------------------------------------------------------------------------------------
private final Logger logger = LoggerFactory.getLogger(SecurityFilter.class);
}
GenericFilter
package com.qrra.PROFIT.web;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
*
* @author Alvin Sim
*/
public class GenericFilter implements Filter {
@Override
public void destroy() {
this.filterConfig = null;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
protected FilterConfig filterConfig = null;
}
I managed to find a fix for this. It’s not actually the filter’s fault, but the
CommandLinkat the logout.jsf. As I was debugging, I saw that upon clicking on the login link, I was getting JavaScript errors injquery.js.jsf?ln=primefaces. There were few objects which were undefined. So I tried to set theCommandLink‘s ajax attribute to “false” and it worked.Why? I am not too sure.