Servlet自從上了3.0版本以後,用起來已是至關舒服了。註解的加入,讓你基本能夠拋棄web.xml,零配置寫web。 java
不過,用了以後,仍是有些遺憾。就是REST風格URL的支持。好久以前用過SpringMVC以後,對於REST風格的URL就喜歡得不得了。上網查了下,發現了個項目servletrest,項目託管在google code上:http://code.google.com/p/servletrest/ git
源碼就幾個類,很快就看完了,也試用了一下。確實是能夠支持,可是bug也比較明顯。最明顯的一個就是,支持了REST的servlet,是沒法獲取到ServletContext。緣由是servletrest在初始化servlet的時候,沒有調用servlet的init方法,即沒有初始化ServletConfig。還有一個問題,就是獲取URI中的參數時,太過繁瑣。並且基於第一個問題,參數實際上是獲取不到的。 web
花了點時間,從新寫了個新的實現,叫summer-restful。主要做用,就是讓普通的servlet支持rest風格的url,而且也修復中servletrest的明顯bug。 restful
定義一個Filter。 app
在容器啓動的時候,對全部已經過註解標記的servlet進行掃描驗證。這裏提到的註解是咱們自定義的,叫@SummerServlet,參數有兩個,name,UrlPatterns。符合規則的servlet初始化,並用他們的urlPatterns做爲該servlet的key,存入一個Map中進行維護。說明下,咱們自定義的@SummerServlet中的urlPatterns,跟原生servlet的UrlPatterns有些區別。自定義的urlPatterns中,是支持相似這種格式的url:/*/detail/* 的,也經過這裏,讓普通的servlet支持了REST風格的url。 jsp
過濾器攔截全部請求。分析請求的servletPath,跟Map中的key進行比對,若匹配,則返回key對應的servlet,而且會注入url中的參數到request;不然,執行默認的動做。 ide
有兩個步驟。 google
經過web.xml配置的話,例子以下 url
<filter> <filter-name>summerFilter</filter-name> <filter-class>cn._5iurl.restful.SummerFilter</filter-class> <init-param> <param-name>servletPackage</param-name> <param-value>cn._5iurl.test.servlet</param-value> </init-param> </filter> <filter-mapping> <filter-name>summerFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>也能夠經過註解來配置。這時候須要新建一個Filter繼承SummerFilter,例子以下
@WebFilter(filterName="restFilter", initParams=@WebInitParam(name="servletPackage", value="cn._5iurl.test.servlet"), urlPatterns="/*") public class CRestFilter extends SummerFilter{ }
在須要Rest風格URL的servlet類中,再也不配置到xml或者用@WebServlet註解,而是改用@SummerServlet註解。例子以下 spa
@SummerServlet(name="detailServlet", urlPatterns="/*/detail/*") public class DetailServlet extends HttpServlet{ private static final long serialVersionUID = 8268477143225755822L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String category = (String)req.getAttribute("p0"); String id = (String)req.getAttribute("p1"); req.setAttribute("id", id); req.getRequestDispatcher("/WEB-INF/www/"+category+"/detail.jsp").forward(req, resp); } }
獲取url中的參數。啥意思呢?仍是上面的例子。假設用戶訪問的是:http://localhost:8015/cms/user/detail/1,能夠看到,是符合咱們定義的url規則:
/*/detail/*那咱們怎麼獲取中隱藏其中的參數值:user和1呢。仍是看例子
String category = (String)req.getAttribute("p0"); String id = (String)req.getAttribute("p1");
源碼已經放在Git@OSC上面,有興趣能夠看下:http://git.oschina.net/cevin15/summer-restful