2019独角兽企业重金招聘Python工程师标准>>>

  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{@Overridepublic 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) {//请求没有找到对应的处理类,返回404if (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.");elsehandle(actionUrl, request, response, isHandled);//处理ActionRender.getActionUrlreturn ;}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

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

  1. Spring源码解析 -- SpringWeb请求参数获取解析

    Spring源码解析 – SpringWeb请求参数获取解析 简介 在文章:Spring Web 请求初探中,我们看到最后方法反射调用的相关代码,本篇文章就探索其中的参数是如何从请求中获取的 概览 方 ...

  2. Spring源码解析 -- SpringWeb请求映射Map初始化

    简介 在上篇文章中,大致解析了Spring如何将请求路径与处理方法进行映射,但映射相关的初始化对于我们来说还是一团迷雾 本篇文章就来探索下,请求路径和处理方法的映射,是如何进行初始化的 概览 基于上篇 ...

  3. Spring 源码解析 -- SpringWeb请求映射解析

    Spring 源码解析 – SpringWeb请求映射解析 简介 基于上篇请求路径初步探索,了解到了一个请求到具体处理方法的大致路径,本篇就继续探索,看下路径是如何匹配到处理方法的 概览 基于上篇:S ...

  4. Eureka Server源码解析(服务故障下线剔除流程)

    原创不易,转载注明出处 系列文章目录 <SpringCloud Eureka Server源码解析(启动流程)> <Eureka Server源码解析(服务注册流程)> < ...

  5. statement执行insert into语句_【图文并茂】源码解析MyBatis ShardingJdbc SQL语句执行流程详解...

    源码分析Mybatis系列目录: 1.源码分析Mybatis MapperProxy初始化[图文并茂] 2.源码分析Mybatis MappedStatement的创建流程 3.[图文并茂]Mybat ...

  6. 源码解析 --skywalking agent 插件加载流程

    1. 插件 目前很多框架,都采用框架 + 插件的模式开发. 如DataX.FlinkX通过插件支持众多异构数据源, Skywalking通过插件实现针对很多软件如redis.mysql.dubbo等方 ...

  7. springcloud gateway 源码解析、请求响应流程、第三方响应结果在 gateway 的经过

    大家好,我是烤鸭: 1.  官方介绍 官方文档: 看的是 2.2.5.RELEASE 版本的 https://docs.spring.io/spring-cloud-gateway/docs/2.2. ...

  8. android glide流程解析,Glide 源码解析(一):简单流程分析

    这篇文章上次修改于 839 天前,可能其部分内容已经发生变化,如有疑问可询问作者. 这篇文章是这个系列的第一篇文章,我第一次写这样连续系列的文章,我先一层一层的剥开 Glide ,如果谁有更好的想法欢 ...

  9. 从源码解析-Android中View的绘制流程及performTraversals方法

    谈谈Activity的setContentView是怎么加载XML视图的 谈谈Activity的View怎么与View绘制工具ViewRootImpl关联的 在前面两篇文章中分析了View是如何跟绘制 ...

最新文章

  1. 【JZOJ3236】矮人排队
  2. phpwind 8.7 发布主题 分析
  3. php 访问 memcache,memcache+php实现页面访问的加速
  4. python数据库self函数_Python常用功能函数系列总结(四)之数据库操作
  5. python替代技术,Python超级方法和调用替代品
  6. linux ssh无需密码,linux下 ssh 实现无需密码的远程登陆
  7. 计算机考研379分,考研379分报考南开大学被刷,是调剂还是二战?师姐建议非常肯定...
  8. [剑指offer][JAVA]面试题第[46]题[把数字翻译成字符串][递归][逆推]
  9. 河南省高考让不让带计算机,河南高考2018严禁携带的东西有哪些?这种衣服不能进考场...
  10. 【GoLang】golang 最佳实践汇总
  11. 黑盒测试只会点点点 这些你都需要知道
  12. 1.1 学习之初;1.2 约定;1.3 认识Linux;1.4 创建虚拟机;1.5安装centos7
  13. 查询数据表里所有重复里的单条记录
  14. 【Codeforces contest-1214 E】Petya and Construction Set【树上构造】
  15. H.266代码学习:xCheckRDCostMerge2Nx2N函数
  16. 中心药库管理系统 v6.85 是什么
  17. SRSniffer抓包工具的使用
  18. 关于个人如何接入微信支付接口,适用于h5,小程序等应用场景
  19. Win7系统中,如何关闭Windows默认的防火墙? win7如何关闭防火墙
  20. 2011年国内手机市场如何推演?

热门文章

  1. IDL 建立影像金字塔
  2. Access(JET-SQL)问题集锦
  3. EnterpriseLibrary 介绍
  4. 【RobotStudio学习笔记】(一)软件的安装与初步测试
  5. (二十二)用RANSAC算法来求线性回归模型的参数
  6. 基础算法 -- 贪心算法
  7. abstract class 抽象类的使用
  8. oracle .net 中文,asp.net查出 oracle数据库中的中文乱码问题
  9. vbs获取程序窗体句柄_VBS调用windows api函数(postmessage)实现后台发送按键脚本...
  10. python51课视频_【Python 课堂】第51课—— and-or技巧