Dashboard > WebWork 1 > WebWork CookBook > Using JSTL seamlessly with WebWork
  WebWork 1 Log In View a printable version of the current page.  
  Using JSTL seamlessly with WebWork
Added by Jason Carreira, last edited by Hani Suleiman on Apr 25, 2004  (view change)
Labels: 
(None)

Webwork works with a Value Stack concept. Every object you need to access from WebWork, wether from the Action itself or from a JSP page, using the supplied taglibs, comes from the Value Stack.

JSTL, on the other hand, works with request attributes. Usually, it would be very cumbersome to access the WebWork Value Stack from JSTL tags. The follwing is a one way to make JSTL work seamlessly with the WebWork Value Stack.

The following filter wraps every HttpServletRequest on a custom class, overriding the getAttribute method. The overriden method will look in the Value Stack if a corresponding request attribute isn't found. This way, you can use JSTL to access the WebWork value stack without any further exercising.

JSTLFilter.java

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class JSTLFilter implements javax.servlet.Filter {

	FilterConfig _filterConfig;

	public FilterConfig getFilterConfig() {
		return _filterConfig;
	}

	public void setFilterConfig(FilterConfig filterConfig) {
		_filterConfig = filterConfig;
	}

	public void init(FilterConfig filterConfig) throws ServletException {
	}

	public void doFilter(ServletRequest request, ServletResponse response, 
                                   FilterChain chain)
			throws IOException, ServletException {
		// Make sure it is an HttpServletRequest, if so, 
              //create the wrapper and pass it on
		if (request instanceof HttpServletRequest) {
			ServletRequest wrappedRequest = 
                           new JSTLRequestWrapper((HttpServletRequest)request);
			chain.doFilter(wrappedRequest, response);
		} else {
		// Otherwise, just pass the request on down the chain
			chain.doFilter(request, response);
		}
	}

	public void destroy() {

	}
}

This is the filter that will wrap every request on the custom wrapper, detailed below. If you're using a servlet 2.3 container the filter may be run every time there is a forward / include. Try the following code to only run the filter once per request:

public class JSTLFilter implements javax.servlet.Filter {
    private static final String RUNONCE_REQUEST_ATTRIBUTE = 
         "__run_once_" + JSTLFilter.class.getName();
    private static final Object RUNONCE_REQUEST_VALUE = new Object();
    FilterConfig _filterConfig;
    public FilterConfig getFilterConfig() {
        return _filterConfig;
    }
    public void setFilterConfig(FilterConfig filterConfig) {

        _filterConfig = filterConfig;
    }
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void doFilter(ServletRequest request, ServletResponse response, 
                                FilterChain chain) throws IOException, 
                                                                    ServletException {
        Object attribute = request.getAttribute(RUNONCE_REQUEST_ATTRIBUTE);
        // Make sure it is an HttpServletRequest, 
        // if so, create the wrapper and pass it on
        if (attribute == null && request instanceof HttpServletRequest) {
            ServletRequest wrappedRequest = 
                         new JSTLRequestWrapper((HttpServletRequest) request);
            chain.doFilter(wrappedRequest, response);
            request.setAttribute(RUNONCE_REQUEST_ATTRIBUTE, 
                                          RUNONCE_REQUEST_VALUE);
        } else {
            // Otherwise, just pass the request on down the chain
            chain.doFilter(request, response);
        }
    }
    public void destroy() {
    }
}

JSTLRequestWrapper.java

import webwork.util.ValueStack;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;

public class JSTLRequestWrapper extends HttpServletRequestWrapper{
	private ServletRequest wrappedRequest;

	public JSTLRequestWrapper(HttpServletRequest request) {
		super(request);
		wrappedRequest = request;
	}

	public Object getAttribute(String s) {
		Object attr = super.getAttribute(s);
		if (null != attr) {
			return attr;
		} else {
			// If not found, then try the ValueStack
			ValueStack stack = ValueStack.getStack(wrappedRequest);
			if (null == stack) return null;
			else return stack.findValue(s);
		}
	}
}

This is the custom request wrapper that overrides the getAttribute method to also look in the Value Stack when a request attribute isn't found. Please note that the above code works only with WebWork 1.x, not with WebWork2. If you're using WebWork2, modify the getAttribute method:

public Object getAttribute(String s) {
    Object attribute = super.getAttribute(s);
    if (attribute == null) {
        // If not found, then try the ValueStack
        OgnlValueStack stack = ActionContext.getContext().getValueStack();
        if (stack != null) {
            attribute = stack.findValue(s);
        }
    }
    return attribute;
}

The filter mapping should look something like this (you'll probably want the filter to be in a more sensible package):

<filter>
  <filter-name>jstlfilter</filter-name>
  <filter-class>JSTLFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>jstlfilter</filter-name>
  <url-pattern>*.jsp</url-pattern>
</filter-mapping>

<filter-mapping>
  <filter-name>jstlfilter</filter-name>
  <url-pattern>*.action</url-pattern>
</filter-mapping>

has anyone tested this on a few different containers ?

i.e. Tomcat / Jetty / Resin / Orion Server ?

I had heard that the pageContext object doesn't have to map to the request attributes map.

Any thoughts ?

Posted by Cameron Braid at Apr 15, 2003 05:43 | Permalink

I've tested it on Resing.

Posted by Anonymous at Jul 14, 2003 06:24 | Permalink

Resin

Posted by Anonymous at Jul 14, 2003 06:24 | Permalink
Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.9 Build:#527 Sep 07, 2006) - Bug/feature request - Contact Administrators