二级域名的java实现
涉及到为用户提供一个二级域名功能,实现方法如下: (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