二级域名的java实现

二级域名的java实现

最近在做一个自建网站平台( http://www.yowob.com ),其他涉及到为用户提供一个二级域名功能,实现方法如下:

(1)首先要在域名服务商端做一个泛域名解析. 我用的是godaddy.com,就新建一个A记录(host=*,point to指向我的服务器的ip),这样所有二级域名都会转到我的服务器来了

(2)接着在web.xml配一个自已写的域名过滤器,

    <filter>
        <filter-name>URLFilter</filter-name>
        <filter-class>com.yowob.commons.URLFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>URLFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

过滤器的代码如下。这里先将二级域名和全球域名和用户ID的映射,保存在一个数据表里, 然后访问进来时对地址做一个判断, 再取出对应的用户ID. 再转一下就行了. 我的静态文件都在static目录,所以还加了一个static的判断。
比如: http://time.you.com/board/21 用time对应用户ID为6,则访问效果有  http://www.you.com/6/board/21相同, 不过地址栏还是显示 http://time.you.com/board/21。
再比如:htttp://www.userdomain.com/board/21,这个是用户ID为6的全球域名,访问效果也和上面一样。

package  com.yowob.commons;

import  java.io.IOException;
import  java.util.HashMap;
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  org.apache.commons.lang.StringUtils;
import  org.apache.commons.lang.math.NumberUtils;
import  org.apache.commons.logging.Log;
import  org.apache.commons.logging.LogFactory;

import  com.yowob.Constants;
import  com.yowob.dao.SiteDAO;
import  com.yowob.dto.SiteDTO;

public   class  URLFilter  implements  Filter {
    
private   static   final  Log log  =  LogFactory.getLog(URLFilter. class );
    
private   static   final  String DOMAIN_END  =   " . "   +  Constants.DOMAIN;  // .you.com
     private   static   final  Map < String, Long >  NAME_MAP  =   new  HashMap < String, Long > ();
    
private   static   final  Map < String, Long >  DOMAIN_MAP  =   new  HashMap < String, Long > ();

    @Override
    
public   void  init(FilterConfig filterConfig)  throws  ServletException {
        log.info(
" ------------------------------init " );
        SiteDAO siteDAO 
=   new  SiteDAO();
        List
< SiteDTO >  list  =  siteDAO.getAll();
        
for  (SiteDTO siteDTO : list) {
            String name 
=  siteDTO.getName();
            
if  (StringUtils.isNotEmpty(name)) {
                NAME_MAP.put(name, siteDTO.getId());
            }
            String domain 
=  siteDTO.getDomain();
            
if  (StringUtils.isNotEmpty(domain)) {
                DOMAIN_MAP.put(domain, siteDTO.getId());
            }
        }
    }

    
public   static   void  updateName(String oldValue, String newValue, Long siteId) {
        
if  (StringUtils.equals(oldValue, newValue)) {
            
return ;
        }
        
if  (StringUtils.isNotEmpty(oldValue)) {
            NAME_MAP.remove(oldValue);
        }
        
if  (StringUtils.isNotEmpty(newValue)) {
            NAME_MAP.put(newValue, siteId);
        }
    }

    
public   static   void  updateDomain(String oldValue, String newValue, Long siteId) {
        
if  (StringUtils.equals(oldValue, newValue)) {
            
return ;
        }
        
if  (StringUtils.isNotEmpty(oldValue)) {
            DOMAIN_MAP.remove(oldValue);
        }
        
if  (StringUtils.isNotEmpty(newValue)) {
            DOMAIN_MAP.put(newValue, siteId);
        }
    }

    @Override
    
public   void  destroy() {
        log.info(
" ------------------------------destroy " );
    }

    @Override
    
public   void  doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain filterChain)  throws  IOException, ServletException {
        HttpServletRequest request 
=  (HttpServletRequest) servletRequest;
        String requestURI 
=  request.getRequestURI();
        String serverName 
=  request.getServerName().toLowerCase();
        String realURI 
=  getRealRequestURI(serverName, requestURI);
        request.getRequestDispatcher(realURI).forward(request, response);
    }

    
private  String getRealRequestURI(String serverName, String requestURI) {
        
if  (Constants.WWW_DOMAIN.equals(serverName)  ||  requestURI.startsWith( " /static/ " ||  Constants.DOMAIN.equals(serverName)) {
            
return  requestURI;
        }
        
if  (serverName.endsWith(DOMAIN_END)) {
            String secondDomain 
=  serverName.substring( 0 , serverName.indexOf( " . " ));
            
// 网站id
             if  (NumberUtils.isNumber(secondDomain))
                
return  getURI(secondDomain, requestURI);
            
// 网站英文名
            Long siteId  =  NAME_MAP.get(secondDomain);
            
if  (siteId  ==   null ) {
                
// 保留的二级域名
                 if  (Constants.isPrivateSecondDomain(secondDomain)) {
                    
return  requestURI;
                }
                
return   " /message?msg=不存在二级域名 "   +  secondDomain;
                
//                 throw new RuntimeException("do not exist second domain: " + secondDomain);
            }
            
return  getURI(siteId  +   "" , requestURI);
        }
        
// 域名
        Long siteId  =  DOMAIN_MAP.get(serverName);
        
if  (siteId  ==   null ) {
            
return  requestURI;
        } 
else  {
            
return  getURI(siteId  +   "" , requestURI);
        }
    }

    
private   static  String getURI(String siteId, String requestURI) {
        
if  (requestURI.equals( " / " )) {
            
return   " / "   +  siteId;
        } 
else  {
            
return   " / "   +  siteId  +  requestURI;
        }
    }

}


其他一些小技巧:
(1)为了便于本机测试,可以修改windows 的hosts文件。我的如下:
127.0 . 0.1        localhost
127.0 . 0.1        you.com
127.0 . 0.1        www.you.com
127.0 . 0.1        time1.you.com
127.0 . 0.1        time2.you.com
127.0 . 0.1         6 .you.com
127.0 . 0.1        www.bobo.com

(2)web页的各种地址则要注意相对路径的问题。主要考虑
首先设置<base href="http://www.yowob.com/" />,或<base href="http://www.yowob.com/6/" />其中地址最后要加一个/
然后页面中其他地址前面不加/,就是相对地址(以地址栏为基础)。加上/,则是绝对地址。

你可能感兴趣的:(二级域名的java实现)