java实现泛域名解析,附SpringMVC源码示例

所谓“泛域名解析”是指:利用通配符 * (星号)来作次级域名以实现全部的次级域名均指向同一IP地址。html

例如支付宝的域名是www.alipay.com前端

域名下面有帮助中心help.alipay.com 、abc.alipay.com 等等子站点。有实力的公司通常都是经过硬件的方式来实现的java

可是对于通常人,这么作投入太大,能够经过程序来实现伪的“泛解析”程序员

好比:javaeye,目前就是经过代码来实现的泛解析。javaeye是ruby的,具体实现感兴趣的能够找找看,原理都是相似的web

一样的java也能够实现。java实现方式。1,修改DispatcherServlet。2,经过fielter实现。spring

第一种方法,若是是本身来作重写DispatcherServlet也不是什么难事,可是这么作入侵性太大,性能好一点。后端

第二种方法,经过fielter实现,入侵相对小点。ruby

如今主要发一下fielter实现的方式。架构

上图是示例程序的目录结构,经过mvn自动生成的。app

核心的处理fielter

[java] view plain copy /**

  • 虚拟域名实现。<br>

  • <li>http://二级域名.域名/目标页面/参数

  • <li>http://blog.test.com ==> http://www.test.com/blog/

  • <li>http://blog.test.com/article/1633 ==> http://www.test.com/blog/article.htm?id=1633

  • @author yuezhen

  • @version $Id: DomainFielter.java,v 0.1 2010-3-17 下午01:21:59 yuezhen Exp $ */
    public class DomainFielter implements Filter {
    private static final String DOMAIN = "alipay-local.com";
    private static final String SEP = "/";

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException,
    ServletException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    String domainName = "";

    // 获取域名  
     String serverName = request.getServerName();  
    
     // 获取请求路径  
     String path = httpServletRequest.getRequestURI();  
    
     // 判断是不是三级域名  
     int end = serverName.indexOf(DOMAIN);  
    
     // 获取domain  
     if (end != -1 && end != 0) {  
         domainName = serverName.substring(0, end - 1);  
     } else {  
         domainName = "www";  
     }  
    
     // 获取目标页面(可选,http://username.test.com/article/1633)获取后面的参数  
     String distPage = getDistPage(path);  
     String id = getId(path);  
    
     // domain不为空  
     if (domainName != null && !"".equals(domainName) && !"www".equals(domainName)) {  
         // http://blog.test.com/article/1633  ==>  http://www.test.com/blog/article.htm?id=1633  
         if (id != null && !id.equals("")) {  
             httpServletRequest.getRequestDispatcher(  
                 SEP + domainName + SEP + distPage + ".htm" + "?id=" + id).forward(request,  
                 response);  
             return;  
         } else {  
             // http://blog.test.com  ==>  http://www.test.com/blog/  
             httpServletRequest.getRequestDispatcher(domainName + SEP)  
                 .forward(request, response);  
             return;  
         }  
     }  
    
     chain.doFilter(request, response);

    }
    在fielter里面咱们会作两件事情

http://blog.test.com ==> http://www.test.com/blog/ http://blog.test.com/article/1633 ==> http://www.test.com/blog/article.htm?id=1633

因为是代码层面实现的转发,因此须要存在一点的url规则。

[xhtml] view plain copy <filter>
<filter-name>DomainFielter</filter-name>
<filter-class>org.fielter.domain.test.DomainFielter</filter-class>
</filter>
<filter-mapping>
<filter-name>DomainFielter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>  
    <servlet-name>dispatcherServlet</servlet-name>  
    <servlet-class>org.springframework.web.servlet.DispatcherServlet  
        </servlet-class>  
    <load-on-startup>2</load-on-startup>  
</servlet>  
  
<servlet-mapping>  
    <servlet-name>dispatcherServlet</servlet-name>  
    <url-pattern>/*</url-pattern>  
</servlet-mapping>

web.xml中只须要将请求转发过来便可。并将url经过过滤器来转换

本例中还有velocity的layout使用方法

[xhtml] view plain copy <bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath">
<value>WEB-INF/page/</value>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="suffix">
<value>.vm</value>
</property>
<property name="layoutUrl" value="layout/layout.vm"/>
<!-- if you want to use the Spring Velocity macros, set this property to true -->
<property name="exposeSpringMacroHelpers" value="true"/>
<!-- variable to override layoutUrl -->
<property name="layoutKey" value="layout"/>
<property name="screenContentKey" value="screen_content"/>

</bean>

这样就velocity就能够很方便的使用了。

图片是访问页面的结果,一个blog的二级域就OK了

题外话:java仍是太臃肿了,适合大企业,IDE很强大,各类语法错误,编译错误在早期能快速的被发现,当系统搭建完毕以后没必要担忧会有什么大问题,只须要招一堆程序员在上面搞业务就好了,处理复杂的业务是强项,不过确实是太臃肿了。

流行的三层架构,若是是web2.0用java搞会疯掉的,一个web层小问题的修改,哪怕一行代码,你要从新编译、部署。。。因此适当的把web层用脚本语言来作确定效率是迅速的,好比,后端很复杂的逻辑所有java实现封装,前端的展现,数据的校验,交互所有能够经过脚本语言来实现,效率确定是空前的高效。

可是也会带来一些新的问题(代码太过自由化很差控制,错误在初期不容易发现)至少目前国内尚未这方面结合的公司有应用的生产环境,可是若是想追求效率,这么作确定是没问题的,至少我是这么认为的。固然公司可能会以为招聘人员的成本增长了。原本招一个java的程序员全部均可以搞了,如今还要招不一样的人作不一样的事。

附:源码点此下载

源码为mvn的例子,只用在根目录,mvn jetty:run便可运行

由于是测试二级域名的解析,因此要配置host。

C:/WINDOWS/system32/drivers/etc/host文件中增长 127.0.0.1 blog.xxx.com photo.xxx.com来测试

相关文章
相关标签/搜索