JFinal源码解析--从请求到处理返回流程

  1. JFinalFilter类doFilter 请求入口

    将请求交由Handler链处理

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+责任链模式的一个变种。

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方法等

  • Controller controller = action.getControllerClass().newInstance();通过action的保存的controller类用反射的方法得到controller实例

  • new ActionInvocation(action, controller).invoke();执行controller的method方法,最后通过调用renderxxx方法,生成对应的响应,保存到controller的render属性上

    /**
     * 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实例

  /**
     * 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);
            }
    }





转载于:https://my.oschina.net/u/1182234/blog/266475

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值