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來測試

相關文章
相關標籤/搜索