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);
            }
    }
相关文章
相关标签/搜索