Sunday, May 15, 2011

Managing multiple Domain and Sub Domain on Google App Engine for Same Application

Google App engine is great and at some time you may end up writing a app which gets popular and you want to use the same application for different domain and different sub-domain but show different site based on same underlying data.

e.g. you are writing a site which will show all data from india
Now say you got another domain or,(Delhi is a city of Country India) which shows data of delhi only. so you want to use same data saved in on and vice versa.
And this tutorial can help you to do exactly same thing

Technologies/Framework used
  1. Spring MVC 3.0+
Spring MVC's annotation based controller is quite handy to use in different situation where url remains same but some header parameter is different or url parameter is different. i.e. You can write two different controller for the same url which will be invoked based on what are the parameters etc.
You can read more sbout such Spring controllers here

Now lets understand how this will work.
  • First we need to identify whethere my application url is called as or
  • Once its identified we will modify the incoming request and let it to be handled by Spring dispatcher servlet
  • Different controller implementation for different urls
    • One Controller for
    • One controller for

First Implement a filter to check every request

Implement a filter to identify domain or subdomain, lets call it DomainFilter

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

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

public class DomainFilter implements Filter {
    private FilterConfig filterConfig;
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
        throws IOException, ServletException {
        MyServletRequestWrapper httpRequest = new MyServletRequestWrapper((HttpServletRequest)request);
         // Do not worry about MyServletRequestWrapper class, its implemented next
        String subDomain = getSubDomain(httpRequest);
  httpRequest.addHeader("subdomain", subDomain);
        filterChain.doFilter(httpRequest, response);
    private String getSubDomain(HttpServletRequest httpRequest){
     //You can implement this function :) just to get www out of or test out of
  return "www";
    public FilterConfig getFilterConfig() {
        return filterConfig;

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

MyServletRequestWrapper : Class HttpServletRequest do not provide any method to modify Header in request so i extended HttpServletRequestWrapper to add this functionality.

public class MyServletRequestWrapper extends HttpServletRequestWrapper{

        private Map<String, String> headerMap;
        public void addHeader(String name, String value){
            headerMap.put(name, new String(value));
        public MyServletRequestWrapper(HttpServletRequest request){
            headerMap = new HashMap<String, String>();

        public Enumeration getHeaderNames(){
            HttpServletRequest request = (HttpServletRequest)getRequest();
            List list = new ArrayList();
            for( Enumeration e = request.getHeaderNames() ; e.hasMoreElements() ;)
            for( Iterator i = headerMap.keySet().iterator() ; i.hasNext() ;){
            return Collections.enumeration(list);
        public String getHeader(String name){
            Object value;
            if((value = headerMap.get(""+name)) != null)
                return value.toString();
                return ((HttpServletRequest)getRequest()).getHeader(name);

Now apply this filter to all incoming request in web.xml

    </filter>    <filter-mapping>

Now create a Spring Controller to handle www and other subdomain

    public class IndexController extends BaseController{
 //Follwoing controller will be called for url
 @RequestMapping(value = "/index.html", method = RequestMethod.GET, headers="subdomain=www")
 public String mainIndexPage(Model model,HttpServletRequest request) {
  return "wwwindexpage";
//Follwoing controller will be called for url
 @RequestMapping(value = "/index.html", method = RequestMethod.GET, headers="subdomain=test")
 public String subsiteIndexPage(Model model,HttpServletRequest request) {
  return "subdomainindexpage";


And now you are ready with your two different controller to handle two different url one with www and one with test.

Let me know if you end up with any problem

1 comment:

  1. The main advantage of multi-domain SSL certificate is that it protects a primary domain and at the most 99 Subject Alternative Names (also known as SAN) in a single certificate. In recent years, multi-domain certificates have become popular due to the advantages that they offer.