JFinalFilter類doFilter 請求入口java
將請求交由Handler鏈處理app
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; request.setCharacterEncoding(encoding); String target = request.getRequestURI();//請求路徑 if (contextPathLength != 0) target = target.substring(contextPathLength);//截去請求的IP域名部分 boolean[] isHandled = {false}; try { handler.handle(target, request, response, isHandled);//交由Handler鏈處理 } catch (Exception e) { if (log.isErrorEnabled()) { String qs = request.getQueryString(); log.error(qs == null ? target : target + "?" + qs, e); } } if (isHandled[0] == false) chain.doFilter(request, response); }
2.MyHandler類 自定義的handler類,在handler里加入本身的方法好比:網站改版,須要在新網站上兼容老網站上的url時能用到,只須要在Handler中將老網站url轉換成新的就能夠了。在處理完以後必須加上nextHandler.handle(target, request, response, isHandled);這樣才能遍歷到咱們添加的handler類。JFinal的Handler是AOP+責任鏈模式的一個變種。ide
public class MyHandler extends Handler{ @Override public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) { System.out.println("-----myhandler is working-----"); nextHandler.handle(target, request, response, isHandled); } }
3.ActionHandler類 添加在handler鏈的尾部,封裝了對action及interceptor的處理
網站
Action action = actionMapping.getAction(target)//actionMapping是咱們在初始化過程當中將請求的URL-處理Action保存在map中,以URL做爲key,Action做爲value。而Action中封裝着處理請求的controller類,method方法等this
Controller controller = action.getControllerClass().newInstance();經過action的保存的controller類用反射的方法獲得controller實例url
new ActionInvocation(action, controller).invoke();執行controller的method方法,最後經過調用renderxxx方法,生成對應的響應,保存到controller的render屬性上spa
/** * handle * 1: Action action = actionMapping.getAction(target) * 2: new ActionInvocation(...).invoke() * 3: render(...) */ public final void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) { if (target.indexOf(".") != -1) { return ; } isHandled[0] = true; String[] urlPara = {null}; Action action = actionMapping.getAction(target, urlPara); if (action == null) {//請求沒有找到對應的處理類,返回404 if (log.isWarnEnabled()) { String qs = request.getQueryString(); log.warn("404 Action Not Found: " + (qs == null ? target : target + "?" + qs)); } renderFactory.getErrorRender(404).setContext(request, response).render();//返回404頁面 return ; } try { Controller controller = action.getControllerClass().newInstance();//經過反射獲得controller實例 controller.init(request, response, urlPara[0]);//初始化controller類 if (devMode) {//調試模式 boolean isMultipartRequest = ActionReporter.reportCommonRequest(controller, action);//打印請求信息 new ActionInvocation(action, controller).invoke(); if (isMultipartRequest) ActionReporter.reportMultipartRequest(controller, action); } else { new ActionInvocation(action, controller).invoke(); } Render render = controller.getRender();//取得controller的render屬性 if (render instanceof ActionRender) {//若是是ActionRender則做爲新的請求處理 String actionUrl = ((ActionRender)render).getActionUrl(); if (target.equals(actionUrl)) throw new RuntimeException("The forward action url is the same as before."); else handle(actionUrl, request, response, isHandled);//處理ActionRender.getActionUrl return ; } if (render == null)//若是render爲空則返回默認的頁面 render = renderFactory.getDefaultRender(action.getViewPath() + action.getMethodName()); render.setContext(request, response, action.getViewPath()).render();// 最後最終 能夠返回給客戶端了 Render to client } catch (RenderException e) { if (log.isErrorEnabled()) { String qs = request.getQueryString(); log.error(qs == null ? target : target + "?" + qs, e); } } catch (ActionException e) { int errorCode = e.getErrorCode(); if (errorCode == 404 && log.isWarnEnabled()) { String qs = request.getQueryString(); log.warn("404 Not Found: " + (qs == null ? target : target + "?" + qs)); } else if (errorCode == 401 && log.isWarnEnabled()) { String qs = request.getQueryString(); log.warn("401 Unauthorized: " + (qs == null ? target : target + "?" + qs)); } else if (errorCode == 403 && log.isWarnEnabled()) { String qs = request.getQueryString(); log.warn("403 Forbidden: " + (qs == null ? target : target + "?" + qs)); } else if (log.isErrorEnabled()) { String qs = request.getQueryString(); log.error(qs == null ? target : target + "?" + qs, e); } e.getErrorRender().setContext(request, response).render(); } catch (Exception e) { if (log.isErrorEnabled()) { String qs = request.getQueryString(); log.error(qs == null ? target : target + "?" + qs, e); } renderFactory.getErrorRender(500).setContext(request, response).render(); } }
4.ActionInvocation類 經過反射執行method,獲得返回給客戶端的render實例.net
/** * Invoke the action. */ public void invoke() { if (index < inters.length) inters[index++].intercept(this); //先執行攔截器,在執行具體方法 else if (index++ == inters.length) // index++ ensure invoke action only one time // try {action.getMethod().invoke(controller, NULL_ARGS);} catch (Exception e) {throw new RuntimeException(e);} try { action.getMethod().invoke(controller, NULL_ARGS);//經過反射執行controller的method方法,進行對應的操做,而後調用render系列方法,render方法中使用工廠模式實例化render類,保存到controller的render屬性上。 } catch (InvocationTargetException e) { Throwable cause = e.getTargetException(); if (cause instanceof RuntimeException) throw (RuntimeException)cause; throw new RuntimeException(e); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } }