手把手教你新建 jfinal 项目 (二)

     前言:上一节,我们新建了一个jfinal 的项目。接下来,我们初步理解下jfinal

    我们理解一个东西,肯定是从我们看到的开始。我们看到了页面,看到了我们访问的地址返回了Hello Jfinal World这个串。我们看看程序的运行。

    一、当我们启动程序时

    1、进入web.xml加载过滤器com.jfinal.core.JFinalFilter,并执行 init 方法,我们来看看这个方法

public void init(FilterConfig filterConfig) throws ServletException {
        private Handler handler;
        private String encoding;
        private JFinalConfig jfinalConfig;
        private Constants constants;
        private static final JFinal jfinal = JFinal.me();
        private static Logger log;
        private int contextPathLength;
      
       /**
             //分步将第一行代码
           1、 filterConfig.getInitParameter("configClass"),
            这方法是获取启动参数,我们在web.xml中配置了
            <init-param>
            <param-name>configClass</param-name>
            <param-value>demo.DemoConfig</param-value>
            </init-param>
            所以这个方法取到的就是 demo.DemoConfig这个字符串
            2、createJFinalConfig("demo.DemoConfig"),主要做了几件事:
            1)反射得到 DemoConfig这个类,并实例化了一个DemoConfig 对象;
            2)jfinalConfig = DemoConfig实例化的对象
            
       */
         createJFinalConfig(filterConfig.getInitParameter("configClass"));
      
        /**
        jfinal.init,这里是根据DemoConfig初始化,主要为:
            initPathUtil();//初始化页面路径
            //初始化插件,暂时没用插件
            Config.configJFinal(jfinalConfig);    // start plugin and init logger factory in this method
            //初始化常量,没用到
            constants = Config.getConstants();
            //初始化 ActionMapping,即 页面请求路径 与 处理请求的action的对应关系。举个栗子:
               在 DemoConfig类中的configRoute(Routes me),我们
                 me.add("/hello", HelloController.class);
                那么此时初始化后,我们就得到了这个一个map
    {
    "hello":{renderText("Hello JFinal World."))}

    }
            如果 HelloController 中 还有其他 方法,例如 delete,add 啊。那么这个map就会变成这样
    {
    "hello":{renderText("Hello JFinal World."))}
    "hello/add":{处理add的action}
    "hello/delete":{处理 delete的action}
    }
          所以最总,我们访问一个地址时,时由它所对应的action来处理的  
            initActionMapping();

            //初始化handler,让 jfinal 中的ActionHandler 成为默认的handler
            initHandler();
            //下面几个就不细说了
            initRender();
            initOreillyCos();
            initI18n();
            initTokenManager();
        */
        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());
    }

看完这个init 方法,我们可以知道的是:它初始化了 路劲对应action的关系,初始化的 默认handler,还有些编码(至于初始化数据库访问插件,因为我们还没用到就不看了)。

    二、当请求来临时 :

    执行 dofilter 方法

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)
        //获取目标路径,这样才能从actionMapping 中找到处理 这个请求的action,我们这是得到target="hello"
            target = target.substring(contextPathLength);
        
        boolean[] isHandled = {false};
        try {
            //这个是关键,此时的handler是actionhandler的实例化对象,我们进去handle方法看一下,源码在下面
            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);
    }

public final void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
        if (target.indexOf(".") != -1) {
            return ;
        }
        
        isHandled[0] = true;
        String[] urlPara = {null};
    //根据hello 从map中获取到处理它的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 {
            //获取处理它的controller这里是HelloController
            Controller controller = action.getControllerClass().newInstance();
            //控制器初始化,拿到 request,response对象,后面就由这个控制器来操作 request和response了,
            
            controller.init(request, response, urlPara[0]);
            
            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();
            }
            //我们的例子最后的结果就是response返回了 Hello JFinal World. 字符串,所以我们页面上看到了字符串
            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).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();
        }
    }


你可能感兴趣的:(手把手教你新建 jfinal 项目 (二))