Jfinal 的路由詳解(五)

路由的使用
實現JfinalConfig,重寫configRoute()方法:

public void configRoute(Routes routes) {
    routes.add("/hello", DemoController.class,"");
}

第一個參數是controllerKey,第二個是自己寫的Controller類,第三個是webApp下的視圖路徑.

路由的源碼實現
configRoute(Routes routes)方法在Config類中別調用.具體如下:

class Config {
	static void configJFinal(JFinalConfig jfinalConfig) {
       	...
        jfinalConfig.configRoute(routes);
        ...
    }
    
	public static final Routes getRoutes() {
        return routes;
    }
}

可以看到Config 類中提供了一個getRoutes()方法,我們看看在Jfinal類中調用這個方法,如下:

public final class JFinal {
	 private void initActionMapping() {
        this.actionMapping = new ActionMapping(Config.getRoutes());
        this.actionMapping.buildActionMapping();
        Config.getRoutes().clear();
    }
}

然後在buildActionMapping方法中使route.getFinalViewPath(routes.getBaseViewPath())添加到Action中去了:

protected void buildActionMapping() {
	 ...
     Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, route.getFinalViewPath(routes.getBaseViewPath()));
     //添加到mapping中
     if (this.mapping.put(actionKey, action) != null) {
                            throw new RuntimeException(this.buildMsg(actionKey, controllerClass, method));
                        }
     ...

這邊封裝好actionmapping在ActionHanle類中handle()方法中會調用
Action action = this.actionMapping.getAction(target, urlPara)獲取action.具體如下:

    public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
        if (target.indexOf(46) == -1) {
            isHandled[0] = true;
            String[] urlPara = new String[]{null};
            Action action = this.actionMapping.getAction(target, urlPara);
            //action爲null反回404
            if (action == null) {
                if (log.isWarnEnabled()) {
                    String qs = request.getQueryString();
                    log.warn("404 Action Not Found: " + (qs == null ? target : target + "?" + qs));
                }

                renderManager.getRenderFactory().getErrorRender(404).setContext(request, response).render();
            } else {
                Controller controller = null;

                try {
                    String actionUrl;
                    try {
                        controller = this.controllerFactory.getController(action.getControllerClass());
                        controller.init(action, request, response, urlPara[0]);
                        if (this.devMode) {
                            if (ActionReporter.isReportAfterInvocation(request)) {
                                (new Invocation(action, controller)).invoke();
                                ActionReporter.report(target, controller, action);
                            } else {
                                ActionReporter.report(target, controller, action);
                                (new Invocation(action, controller)).invoke();
                            }
                        } else {
                            (new Invocation(action, controller)).invoke();
                        }

                        Render render = controller.getRender();
                        if (!(render instanceof ForwardActionRender)) {
                            if (render == null) {
                            //action.getViewPath() 獲取設定的viewpath到指定路徑上
                                render = renderManager.getRenderFactory().getDefaultRender(action.getViewPath() + action.getMethodName());
                            }

                            render.setContext(request, response, action.getViewPath()).render();
                            return;
                        }

                        actionUrl = ((ForwardActionRender)render).getActionUrl();
                        if (target.equals(actionUrl)) {
                            throw new RuntimeException("The forward action url is the same as before.");
                        }

                        this.handle(actionUrl, request, response, isHandled);
                    } catch (RenderException var17) {
                        if (log.isErrorEnabled()) {
                            actionUrl = request.getQueryString();
                            log.error(actionUrl == null ? target : target + "?" + actionUrl, var17);
                        }

                        return;
                    } catch (ActionException var18) {
                        int errorCode = var18.getErrorCode();
                        String msg = null;
                        if (errorCode == 404) {
                            msg = "404 Not Found: ";
                        } else if (errorCode == 401) {
                            msg = "401 Unauthorized: ";
                        } else if (errorCode == 403) {
                            msg = "403 Forbidden: ";
                        }

                        String qs;
                        if (msg != null) {
                            if (log.isWarnEnabled()) {
                                qs = request.getQueryString();
                                log.warn(msg + (qs == null ? target : target + "?" + qs));
                            }
                        } else if (log.isErrorEnabled()) {
                            qs = request.getQueryString();
                            log.error(qs == null ? target : target + "?" + qs, var18);
                        }

                        var18.getErrorRender().setContext(request, response, action.getViewPath()).render();
                        return;
                    } catch (Exception var19) {
                        if (log.isErrorEnabled()) {
                            actionUrl = request.getQueryString();
                            log.error(actionUrl == null ? target : target + "?" + actionUrl, var19);
                        }

                        renderManager.getRenderFactory().getErrorRender(500).setContext(request, response, action.getViewPath()).render();
                        return;
                    }
                } finally {
                    if (controller != null) {
                        controller.clear();
                    }

                }

            }
        }
    }

render.setContext()中的源碼:

public Render setContext(HttpServletRequest request, HttpServletResponse response, String viewPath) {
       this.request = request;
       this.response = response;
       if (this.view != null && this.view.length() > 0 && this.view.charAt(0) != '/') {
           this.view = viewPath + this.view;
       }

       return this;
   }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章