views:

57

answers:

2

Hi, I'm trying to set up a site which allows users to create their own page - as a subdomain of the site, and so what I'm currently trying to do is to have a filter which looks at the subdomain, and if it's not in use, or if it's reserved, then the user will be forwarded to a page where they choose their subdomain name.

The problem that I have is that when I set an attribute on the ServletRequest object, and then forward using the RequestDispatcher, the filter gets called again - but it can't see the attribute that I set.

I've debugged and watched it work (or not work!), and the attribute is being set, but after the forward, the attribute is not there.

Can someone help explain what's going on, and how I might fix this??

I should probably also mention that I'm developing for Java Google App Engine.

Here's my filter code.

import java.io.IOException;
import java.util.Enumeration;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;



public class SubdomainFilter implements Filter{
    private static Logger log = Logger.getLogger(SubdomainFilter.class.getName());
    private static final String[] RESERVED_SUBDOMAINS = {"admin", "home", "www"};
    private static final String registerPage = "/register_a_page";

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        //if we've been forwarded, it must have been because of an invalid subdomain
        if(arg0.getAttribute("subdomain") != null) {
            arg2.doFilter(arg0, arg1);
        } else { //otherwise, look at the subdomain and determine what to do
            boolean invalidSubdomain = false;
            try {
                String requestURLInfo = ((HttpServletRequest)arg0).getRequestURL().toString();
                String subdomain = URLUtils.getLowestSubdomainFromURL(requestURLInfo);
                arg0.setAttribute("subdomain", subdomain);
                if(subdomainReserved(subdomain) || subdomainInUse(subdomain)) {
                    invalidSubdomain = true;
                }//Otherwise the subdomain must be valid
            } catch(Exception ex) {
                log.severe("Filter could not get subdomain:\n" + ex.toString());
            } finally {
                if(invalidSubdomain) {
                    RequestDispatcher dispatcher = arg0.getRequestDispatcher(registerPage);
                    dispatcher.forward(arg0, arg1);
                } else {
                    arg2.doFilter(arg0, arg1);
                }
            }
        }

    }

    private boolean subdomainReserved(String subdomain) {
        boolean subdomainReserved = false;
        for(String reservedSubdomain : RESERVED_SUBDOMAINS) {
            if(reservedSubdomain.equals(subdomain)) {
                subdomainReserved = true;
                break;
            }
        }
        return subdomainReserved;
    }

    private boolean subdomainInUse(String subdomain) {
        boolean subdomainInUse = false;
        //TODO: implement
        return subdomainInUse;
    }
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }

}
A: 

It should work. Either the URLUtils.getLowestSubdomainFromURL() has just returned null, or something else in the request-response chain has fired HttpServletResponse#sendRedirect().

BalusC
Through debugging, getLowestSubdomainFromURL definitely returns the string "www". I don't know if it makes any difference that I'm developing for Google App Engine?
Louis Sayers
A: 

I think the problem was that I didn't declare the following in my web.xml:

<filter-mapping>
   <filter-name>SubdomainFilter</filter-name>
   <servlet-name>*</servlet-name>
   <dispatcher>REQUEST</dispatcher>
   <dispatcher>FORWARD</dispatcher>
</filter-mapping>  
Louis Sayers
What was the exact difference with the original configuration?
BalusC