2012-01-17 127 views
10

我試圖按照Design Patterns web based applications的模式進行操作。從涉及到映射「根」URL時起,這一切都起到了很好的作用。在Tomcat中將URL映射到FrontController servlet

我想通過「前端控制器」把所有的要求,所以我已經把

<servlet-mapping> 
    <servlet-name>ControllerServlet</servlet-name> 
    <url-pattern>/*</url-pattern> 
</servlet-mapping> 

web.xml。步進通過與Netbeans的顯示未來的請求,並操作工作正常,但隨後行

request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response); 

還獲得由控制器抓到,這是不言而喻的行動再次和這一切失敗。

我可以通過不從網址的根目錄開始工作,例如

<servlet-mapping> 
     <servlet-name>ControllerServlet</servlet-name> 
     <url-pattern>/pages/*</url-pattern> 
    </servlet-mapping> 

但這不是我想要的。有什麼辦法可以使它與「根」URL一起工作嗎?

回答

8

/* URL模式涵蓋一切,還轉發的JSP文件和靜態資源,如CSS/JS /圖像。你不希望在前端控制器servlet上擁有這個功能。

保持您的控制器servlet處於更具體的URL模式,如/pages/*。您可以實現通過像/resources一個共同的文件夾分組的靜態資源和創造這是對/*映射一個Filter擺脫在URL「/頁」的功能要求,並執行以下任務的doFilter()方法:

HttpServletRequest req = (HttpServletRequest) request; 
String path = req.getRequestURI().substring(req.getContextPath().length()); 

if (path.startsWith("/resources/")) { 
    // Just let container's default servlet do its job. 
    chain.doFilter(request, response); 
} else { 
    // Delegate to your front controller. 
    request.getRequestDispatcher("/pages" + path).forward(request, response); 
} 

轉發的JSP資源在默認情況下不會與此過濾器匹配,因此它將由容器自己的JspServlet正確拾取。

+0

感謝您的答覆,它看起來複雜,所以它要帶我一段時間才能到達過濾器,現在我就離開一切/頁/ – Mark 2012-01-18 19:06:47

+0

您可以將無延伸請求與path.match(「^。* \\/[^ \\。] * $」)匹配並將其轉發給您的前端控制器。 – Ring 2014-02-05 18:09:32

+0

@BalusC'substring'有什麼意義? – user2418306 2016-01-23 14:55:37

0

/* url模式匹配應用程序中的所有servlet,jsp和靜態內容。

Whay你需要的是定義一個* .JSP模式,讓Tomcat的使用默認的JSP Servlet:

<servlet-mapping> 
    <servlet-name>jsp</servlet-name> 
    <url-pattern>*.jsp</url-pattern> 
</servlet-mapping> 
3

爲什麼我們需要映射每個URL。如果您需要映射所有網址,則可能需要在過濾器中跳過網址。

<filter> 
    <display-name>SessionFilter</display-name> 
    <filter-name>SessionFilter</filter-name> 
    <filter-class>com.colabcom.goshare.app.base.filter.SessionFilter</filter-class> 
    </filter> 
    <filter-mapping> 
    <filter-name>sessionFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    </filter-mapping> 

在你的過濾器,

 HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 
     String url = request.getServletPath(); 
     boolean allowedRequest = Utility.filterURL(url, avoidUrls); 
     if(allowedRequest){ 
      chain.doFilter(request, response); 
     }else{ 
      //Main Filter Code   
     } 

工具類來過濾網址:

public static boolean filterURL(String str, List<String> avoidURLList) { 
    boolean exist = false; 

    if(avoidURLList == null){ 
     return exist; 
    } 
    for (int i = 0; i < avoidURLList.size(); i++) { 
     if (str.contains(avoidURLList.get(i))) { 
      exist = true; 
      break; 
     } 
    } 
    return exist; 
} 

否則,你可以在你的web.xml映射特定的URL像

<filter-mapping> 
    <filter-name>sessionFilter</filter-name> 
    <url-pattern>*.action</url-pattern> 
    </filter-mapping> 
+0

感謝您的回覆,它看起來很複雜,所以我需要一段時間才能過濾,現在我只是將所有內容都留在/ pages/ – Mark 2012-01-18 19:06:56

0

您可以擴展DefaultServlet您的Web服務器。擴展的servlet將成爲您的前端控制器。在doGET或doPOST方法中,將靜態頁面轉發給超類。 DefaultServlet是默認映射到url「/」的servlet。我用它與jetty服務器,但它也可以在tomcat中實現。

public class FrontController extends DefaultServlet { 

@Override 
public void init() throws UnavailableException { 
    super.init(); 
} 

@Override 
protected void doGet(HttpServletRequest request, 
     HttpServletResponse response) throws ServletException, IOException { 

    String uri = request.getRequestURI(); 

    /* 
    * if request is trying to access inside /static then use the default 
    * servlet. YOU CAN USE YOUR OWN BUSINESS LOGIC TO FORWARD REQUESTS 
    * TO DEFAULTSERVLET 
    */ 
    if (uri.startsWith("/static/")) { 

     super.doGet(request, response); 
     return; 
    } else { 

     // else use your custom action handlers 
    } 
} 

}

在上面的代碼樣品我已轉發開始/靜態/到默認的servlet來處理所有請求。通過這種方式,您可以將FrontController映射到「/」級別。

<servlet> 
<description></description> 
<display-name>FrontController</display-name> 
<servlet-name>FrontController</servlet-name> 
<servlet-class>FrontController</servlet-class> 

<servlet-mapping> 
<servlet-name>FrontController</servlet-name> 
<url-pattern>/</url-pattern> 

+0

這是否將您的解決方案綁定到特定容器?換句話說,一旦我將這段代碼寫入到我的應用程序中,然後我就會使用Tomcat或Jetty或之後的任何其他代碼,直到我稍後必須返回並更改此代碼爲止? – Ring 2014-02-05 17:05:38