源码有毒:Jfinal源码解析(六)

本文深入解析JFinal框架的处理流程,包括Handler.handle方法的具体实现、Action的获取与执行过程、拦截器的调用顺序以及Render.render方法的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码有毒:Jfinal源码解析(一)
源码有毒:Jfinal源码解析(二)
源码有毒:Jfinal源码解析(三)
源码有毒:Jfinal源码解析(四)
源码有毒:Jfinal源码解析(五)
继续看Handler.handler方法

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) {
            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 controller = action.getControllerClass().newInstance();
            controller.init(request, response, urlPara[0]);

            if (devMode) {
                if (ActionReporter.isReportAfterInvocation(request)) {
                    new Invocation(action, controller).invoke();
                    ActionReporter.report(controller, action);
                } else {
                    ActionReporter.report(controller, action);
                    new Invocation(action, controller).invoke();
                }
            }
            else {
                new Invocation(action, controller).invoke();
            }

            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) {
        ...异常处理
    }
}

继续往下走,从actionMapping中获取完Action之后,如果没有获取但相应的Action则返回404错误信息,如果Action存在,则从Action中取出初始化时存储到Action中的Controller的Class然后实例化这个Controller

            Controller controller = action.getControllerClass().newInstance();
            controller.init(request, response, urlPara[0]);

紧接着创建了ActionInvocation实例,并调用了invoke()方法

new ActionInvocation(action, controller).invoke();
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);
            }
            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);
            }
    }

在invoke()方法中,显示依次调用了当前action请求对于的拦截器,在所有的拦截器执行完之后,则是调用了具体Action请求对应的Controller中的具体方法

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 ;
            }

如果当前的Action请求是一个重定向请求,则再递归调用handle方法
调用了Render.render()方法,这里看一个简单的例子JsonRender中的render()方法

    public void render() {
        if (jsonText == null)
            buildJsonText();

        PrintWriter writer = null;
        try {
            response.setHeader("Pragma", "no-cache");   // HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);

            response.setContentType(forIE ? contentTypeForIE : contentType);
            writer = response.getWriter();
            writer.write(jsonText);
            writer.flush();
        } catch (IOException e) {
            throw new RenderException(e);
        }
        finally {
            if (writer != null)
                writer.close();
        }
    }

这里代码就比较情切了,把jsonText返回前台调用者,而JsonText在则是把创建JsonRender()对象是传入的数据对象直接转换成了Json字符串

public JsonRender(Object object) {
        if (object == null)
            throw new IllegalArgumentException("The parameter object can not be null.");
        this.jsonText = JsonKit.toJson(object, convertDepth);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值