JFinal源碼解析--從請求處處理返回流程

  1. 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);
            }
    }
相關文章
相關標籤/搜索