JEE Web Filter to fix JSF root context handling

Java JBoss

The JSF implementation in JBoss AS 7/EAP 6 has a small annoyance when it comes to handling of default page in default (root) context and outcome attribute, such as in h:link.

For instance, consider my domain, www.usmans.info. In my blog software, the JSF servlet handles *.xhtml extensions. The default welcome page is set to index.xhtml.

The problem is, if someone hits just the domain, the JSF components which contains 'outcome' attribute does not generate proper URL. For instance, rather then generating http://www.usmans.info/notes.xhtml, it will generate /notes.xhtml only.

To fix this annoyance, I had to set default welcome page as index.jsp, which did a redirect to index.xhtml. However, this workaround caused an unnecessary browser redirect.

To avoid the browser redirect, I introduced a web filter which detects this particular use-case and internally forwards to index.xhtml. This fix the issue and JSF engine renders all targets/outcome correctly. Here is the code:


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

/**
* This filter is to fix an invonvinence where
* JSF link tag's 'outcome' is not calculated correctly
* if application is accessed with just the domain name
* i.e http://www.usmans.info .
*
* We forward the request to index.xhtml if the request URI is just /.
* This is probably just JBoss/Mojarra issue, but we needed this fix
* to avoid having index.jsp which redirect to index.xhtml
*
* @author Usman Saleem
* @version 1.0
*/
@WebFilter(urlPatterns={"/*"})
public class FixRootURIFilter implements Filter {

    private FilterConfig filterConfig = null;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
	if(request instanceof HttpServletRequest) {
		HttpServletRequest httpReq = (HttpServletRequest) request;
		String uri = httpReq.getRequestURI();
		if(uri != null && uri.equals("/")) {
			RequestDispatcher rd = filterConfig.
                                  getServletContext().
                                  getRequestDispatcher("/index.xhtml");
			if(rd != null) {
				rd.forward(request, response);
				return;
			}
		}
	}

	//default handling - do nothing and forward reqeust to filter chain
        chain.doFilter(request, response);

    }
    @Override
    public void destroy() {    }
}