摘要:在中,通過對所有的類進行過濾。在這個類中,均以成員變量的形式存在。中放置的是和的鍵值對。在中主要是調用了方法。
在jfinal中,通過JFinalFilter對所有的類進行過濾。
以下是路由的調用關系(我在調用關系旁邊做了標記,會貼出具體的代碼和解釋):
-1- Config: Routes -2- Interceptors Handlers -3- public void init(){ createJFinalConfig -4- init: initActionMapping: new ActionMapping buildActionMapping -5- initHandler new ActionHandler getHandler initRender } -6- public void dofilter(){ -7- handle: Action action = new actionMapping.getAction(target) -8- new ActionInvocation.invoke() render }
-1-
Config是基本的配置。
在Config這個類中,Routes、Interceptors、Handlers均以成員變量的形式存在。
class Config { private static final Routes routes = new Routes(){public void config() {}}; private static final Interceptors interceptors = new Interceptors(); private static final Handlers handlers = new Handlers(); }
-2-
Routes
在Route中有兩個Map:map和viewPathMap。
map中放置的是controllerKey和controllerClass的鍵值對。
viewPathMap中放置的是controllerKey和viewPath的鍵值對。
public abstract class Routes { private final Map> map = new HashMap >(); private final Map viewPathMap = new HashMap (); public Routes add(String controllerKey, Class extends Controller> controllerClass, String viewPath) { if (controllerKey == null) throw new IllegalArgumentException("The controllerKey can not be null"); // if (controllerKey.indexOf(".") != -1) // throw new IllegalArgumentException("The controllerKey can not contain dot character: ".""); controllerKey = controllerKey.trim(); if ("".equals(controllerKey)) throw new IllegalArgumentException("The controllerKey can not be blank"); if (controllerClass == null) throw new IllegalArgumentException("The controllerClass can not be null"); if (!controllerKey.startsWith("/")) controllerKey = "/" + controllerKey; if (map.containsKey(controllerKey)) throw new IllegalArgumentException("The controllerKey already exists: " + controllerKey); map.put(controllerKey, controllerClass); if (viewPath == null || "".equals(viewPath.trim())) // view path is controllerKey by default viewPath = controllerKey; viewPath = viewPath.trim(); if (!viewPath.startsWith("/")) // "/" added to prefix viewPath = "/" + viewPath; if (!viewPath.endsWith("/")) // "/" added to postfix viewPath = viewPath + "/"; if (baseViewPath != null) // support baseViewPath viewPath = baseViewPath + viewPath; viewPathMap.put(controllerKey, viewPath); return this; } }
-3-
JFinalFilter中的init方法
public void init(FilterConfig filterConfig) throws ServletException { createJFinalConfig(filterConfig.getInitParameter("configClass")); if (jfinal.init(jfinalConfig, filterConfig.getServletContext()) == false) throw new RuntimeException("JFinal init error!"); handler = jfinal.getHandler(); constants = Config.getConstants(); encoding = constants.getEncoding(); jfinalConfig.afterJFinalStart(); String contextPath = filterConfig.getServletContext().getContextPath(); contextPathLength = (contextPath == null || "/".equals(contextPath) ? 0 : contextPath.length()); }
-4-
在JFinalFilter中調用了方法jfinal.init,進行初始化
boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) { this.servletContext = servletContext; this.contextPath = servletContext.getContextPath(); initPathUtil(); Config.configJFinal(jfinalConfig); // start plugin and init logger factory in this method constants = Config.getConstants(); initActionMapping(); initHandler(); initRender(); initOreillyCos(); initTokenManager(); return true; }
-5-
在initActionMapping中將Routes和Interceptors組織起來。其中,在initActionMapping中有一個重要的方法:buildActionMapping
void buildActionMapping() { mapping.clear(); SetexcludedMethodName = buildExcludedMethodName(); ActionInterceptorBuilder interceptorBuilder = new ActionInterceptorBuilder(); Interceptor[] globalInters = interceptors.getGlobalActionInterceptor(); interceptorBuilder.addToInterceptorsMap(globalInters); for (Entry > entry : routes.getEntrySet()) { Class extends Controller> controllerClass = entry.getValue(); Interceptor[] controllerInters = interceptorBuilder.buildControllerInterceptors(controllerClass); boolean sonOfController = (controllerClass.getSuperclass() == Controller.class); Method[] methods = (sonOfController ? controllerClass.getDeclaredMethods() : controllerClass.getMethods()); for (Method method : methods) { String methodName = method.getName(); if (excludedMethodName.contains(methodName) || method.getParameterTypes().length != 0) continue ; if (sonOfController && !Modifier.isPublic(method.getModifiers())) continue ; Interceptor[] methodInters = interceptorBuilder.buildMethodInterceptors(method); Interceptor[] actionInters = interceptorBuilder.buildActionInterceptors(globalInters, controllerInters, methodInters, method); String controllerKey = entry.getKey(); ActionKey ak = method.getAnnotation(ActionKey.class); String actionKey; if (ak != null) { actionKey = ak.value().trim(); if ("".equals(actionKey)) throw new IllegalArgumentException(controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank."); if (!actionKey.startsWith(SLASH)) actionKey = SLASH + actionKey; } else if (methodName.equals("index")) { actionKey = controllerKey; } else { actionKey = controllerKey.equals(SLASH) ? SLASH + methodName : controllerKey + SLASH + methodName; } Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey)); if (mapping.put(actionKey, action) != null) throw new RuntimeException(buildMsg(actionKey, controllerClass, method)); } } // support url = controllerKey + urlParas with "/" of controllerKey Action actoin = mapping.get("/"); if (actoin != null) mapping.put("", actoin); }
-6-
JFinalFilter中的doFilter。在doFilter中主要是調用了handle方法。
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); boolean[] isHandled = {false}; try { handler.handle(target, request, response, isHandled); } 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); }
-7-
handle方法
/** * handle * 1: Action action = actionMapping.getAction(target) * 2: new Invocation(...).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}; //通過url得到action!!! Action action = actionMapping.getAction(target, urlPara); if (action == null) { 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(); return ; } try { //根據action得到controller!!! Controller controller = action.getControllerClass().newInstance(); controller.init(request, response, urlPara[0]); if (devMode) { boolean isMultipartRequest = ActionReporter.reportCommonRequest(controller, action); //用獲得的action進行調用處理請求!!! new Invocation(action, controller).invoke(); if (isMultipartRequest) ActionReporter.reportMultipartRequest(controller, action); } else { new Invocation(action, controller).invoke(); } Render render = controller.getRender(); if (render instanceof 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); return ; } if (render == null) render = renderFactory.getDefaultRender(action.getViewPath() + action.getMethodName()); render.setContext(request, response, action.getViewPath()).render(); } 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, action.getViewPath()).render(); } catch (Throwable t) { if (log.isErrorEnabled()) { String qs = request.getQueryString(); log.error(qs == null ? target : target + "?" + qs, t); } renderFactory.getErrorRender(500).setContext(request, response, action.getViewPath()).render(); } }
-8-
getAction方法:通過url得到action
Action getAction(String url, String[] urlPara) { Action action = mapping.get(url); if (action != null) { return action; } // -------- int i = url.lastIndexOf(SLASH); if (i != -1) { action = mapping.get(url.substring(0, i)); urlPara[0] = url.substring(i + 1); } return action; }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65780.html
摘要:只是暴露接口,配置信息最終保存在的靜態類中。整個項目只有一個,作為靜態類可以保證它是唯一的,而它的靜態成員也是整個項目中唯一的。至此的路由解析模塊就分析完了。 jFinal的路由解析是在JFinalFilter中做的,這個Filter也需要在web.xml中配置。JFinalFilter實現了javax.servlet.Filter接口,從這里也可以看出jFinal是基于Servlet...
摘要:是國產的框架,由五大部分組成。本文通過一個例子上手,旨在熟悉中各組件的用法。指的是表名,指的是主鍵數據庫連接池使用的是,還支持。默認訪問方法,這點類似于如果之前有基礎,上手會非常快。映射在上使用了校驗攔截器,使用了權限攔截器。 JFinal是國產的MVC框架,由 Handler、Interceptor、Controller、Render、Plugin 五大部分組成。本文通過一個例子上手...
摘要:使用在線商品展示系統使用使用導入項目安裝依賴庫啟動項目打開開始使用吧配置如何開發項目可能會用到僅供參考持續開發端所有頁面端所有頁面微信分享后臺商品管理系統后臺管理使用模板簡單效果如下歡迎提問 使用 jfinal+beetl 在線商品展示系統 showImg(https://segmentfault.com/img/remote/1460000009341465);showImg(htt...
摘要:使用在線商品展示系統使用使用導入項目安裝依賴庫啟動項目打開開始使用吧配置如何開發項目可能會用到僅供參考持續開發端所有頁面端所有頁面微信分享后臺商品管理系統后臺管理使用模板簡單效果如下歡迎提問 使用 jfinal+beetl 在線商品展示系統 showImg(https://segmentfault.com/img/remote/1460000009341465);showImg(htt...
閱讀 553·2023-04-26 02:59
閱讀 691·2023-04-25 16:02
閱讀 2154·2021-08-05 09:55
閱讀 3544·2019-08-30 15:55
閱讀 4640·2019-08-30 15:44
閱讀 1797·2019-08-30 13:02
閱讀 2193·2019-08-29 16:57
閱讀 2288·2019-08-26 13:35