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
}
}
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>
It should work. Either the URLUtils.getLowestSubdomainFromURL()
has just returned null
, or something else in the request-response chain has fired HttpServletResponse#sendRedirect()
.
I know this post is 3 years old, but i still want to confirm Louis's post, that forwarding works fine without the following web.xml ONLY IF you don't need attributes forwarded (i.e. request.getAttribute, request.setAttribute).
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
I'm not sure if there is any overhead by specifying the dispatcher tags in the web.xml when you don't NEED to, but you definitely DO need that in the web.xml for attributes to work.
精彩评论