Struts、Ajax、Restful、Web Service 狂想曲框架實(shí)現(xiàn)篇(二)
Posted on 2011-11-25 12:35 馬航 閱讀(274) 評(píng)論(0) 編輯 收藏上篇說(shuō)過(guò),所有提交到web程序的url都被此UrlFilter攔截。攔截到請(qǐng)求后,UrlFilter則召集它的好多個(gè)得力干將Router 們, 詢問(wèn)他們:“誰(shuí)能處理此URL啊 ?”
這時(shí)一位叫做AMP的Router 首當(dāng)其沖 說(shuō):“這個(gè)url交給我了”。這時(shí)filter就會(huì)把此url全權(quán)交給AMPRouter來(lái)辦,至于如何去處理,filter也不再過(guò)問(wèn),它覺(jué)得:“我把任務(wù)都交給你了,怎么解決是你的事”。
根據(jù)單一職責(zé)的原則,UrlFilter就負(fù)責(zé)上面情景中的分發(fā)url到Router中的差事,url如何分發(fā)交給Router處理。并且Router實(shí)際是一個(gè)接口,使用框架的用戶完全可以自己實(shí)現(xiàn)Router,這樣用戶可以自主定義的url分發(fā)的策略。另外呢,框架初始化的一些操作它也是 推脫不掉的,像根據(jù)unicorn-config.xml初始化系統(tǒng)中的Router和Action'。下面是具體的代碼:
@Override public void init(FilterConfig config) throws ServletException { application = config.getServletContext(); String loadPath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); String classPath = loadPath.substring(1, loadPath.length()); ArrayList<String> actions = XMLReader.getNodeValues(classPath + "unicorn-config.xml", "actions"); this.initActions(actions); ArrayList<String> routers = XMLReader.getNodeValues(classPath + "unicorn-config.xml", "routers"); this.initRouters(routers); }
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; String path = request.getContextPath(); String uri = request.getRequestURI(); String relativeUri = uri.substring(path.length(), uri.length()); this.request = request; this.session = request.getSession(); this.response = (HttpServletResponse) servletResponse; // 用戶自定義的Router優(yōu)先級(jí)最高,url先通過(guò)用戶定義的 Iterator<IPathRouter> iterator = routerList.iterator(); while(iterator.hasNext()) { IPathRouter router = iterator.next(); if(router.route(relativeUri, this)) { return ; } } // 攔截不到的繼續(xù)訪問(wèn) filterChain.doFilter(servletRequest, servletResponse); }
其中Router類的初始化,Action類的初始化于這個(gè)類似:
private void initRouters(ArrayList<String> routers) { routerList = new ArrayList<IPathRouter>(); for (int i = 0; i < routers.size(); i++) { String routerName = routers.get(i); try { Class<?> clz = Class.forName(routers.get(i)); // 單例模式通過(guò)方法獲取對(duì)象實(shí)例 IPathRouter router = (IPathRouter) clz.newInstance(); routerList.add(router); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } // 最后把框架默認(rèn)的Router加入進(jìn)來(lái) routerList.add(new AMPPathRouter()); }
其中unicorn-config.xml文件的編寫,拿其中我一個(gè)項(xiàng)目里的這個(gè)文件來(lái)舉例:
<?xml version="1.0" encoding="UTF-8" ?>
<config>
<routers>
<router class="com.mh.router.MySessionCheckRouter"></router>
</routers>
<actions>
<action class="com.mh.action.UserAction"></action>
<action class="com.mh.action.InformationAction"></action>
<action class="com.mh.action.UploadInformationIconAction"></action>
<action class="com.mh.action.TempPicAction"></action>
<action class="com.mh.action.MobileAction"></action>
</actions>
</config>
這里即定義了Action,也定義了自己的Router,并且從名稱上可以看出,這個(gè)SessionCheckRouter是要判斷所有提交到服務(wù)器的指定url的請(qǐng)求 是否已經(jīng)登錄過(guò),沒(méi)有登錄,可能會(huì)把此請(qǐng)求遣送會(huì)登錄頁(yè)。以及初始化所有的Action,在Router處理完請(qǐng)求,分發(fā)給action時(shí),可以從filter里面去取。