今天中午有小伙伴跟我咨询JFinal Handler中的相关姿势,鉴于上次视频中也没有讲清楚,这里特写了一篇博文详细讲解。
##首先我们来看看Handler的配置 在JFinal的Config中可用来配置Handler
@Override
public void configHandler(Handlers me) {
me.add(new FakeStaticHandler());
}
在这个添加JFinal内置或者我们自己的Handler
,在Handlers
中有一个ArrayList
来存储她们。
final public class Handlers {
private final List<Handler> handlerList = new ArrayList<Handler>();
public Handlers add(Handler handler) {
if (handler != null)
handlerList.add(handler);
return this;
}
public List<Handler> getHandlerList() {
return handlerList;
}
}
下面是Handler的初始化
在项目启动JFinalFilter.init
初始化时执行了jfinal.init
完成了对整个框架的初始化!我们的Handler也是在这里完成初始化的。
boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {
this.servletContext = servletContext;
this.contextPath = servletContext.getContextPath();
initPathUtil();
Config.configJFinal(jfinalConfig); // start plugin and init logger factory in this method
constants = Config.getConstants();
initActionMapping();
initHandler();
initRender();
initOreillyCos();
initTokenManager();
return true;
}
// 初始化Handler
private void initHandler() {
Handler actionHandler = new ActionHandler(actionMapping, constants);
handler = HandlerFactory.getHandler(Config.getHandlers().getHandlerList(), actionHandler);
}
大家再来看看HandlerFactory
,在这里从ArrayList的尾部向头部循环,完成对每个Handler
中的nextHandler
参数赋值。
下面是Handler
的结构,她是一个单向的链表。
/**
* Handler.
* <p>
* You can config Handler in JFinalConfig.configHandler() method,
* Handler can do anything under the jfinal action.
*/
public abstract class Handler {
protected Handler nextHandler;
/**
* Handle target
* @param target url target of this web http request
* @param request HttpServletRequest of this http request
* @param response HttpServletRequest of this http request
* @param isHandled JFinalFilter will invoke doFilter() method if isHandled[0] == false,
* it is usually to tell Filter should handle the static resource.
*/
public abstract void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled);
}
再来看看HandlerFactory
中的getHandler
方法。Handler链条的末端是ActionHandler,是专门处理action动态请求的地方。
/**
* Build handler chain
*/
public static Handler getHandler(List<Handler> handlerList, Handler actionHandler) {
Handler result = actionHandler;
for (int i=handlerList.size()-1; i>=0; i--) {
Handler temp = handlerList.get(i);
temp.nextHandler = result;
result = temp;
}
return result;
}
最后我们来看看Handler是怎么工作的
上图描述了JFinal中的一个请求的完整过程JFinalFilter->Handler->Action
请求到达Handler
中之后有三种结局(冥冥中,早已注定我们的三世情缘)
① 直接跳出链条,执行下一个Filter(如果web.xml中有配置)tomcat、jetty容器对静态资源请求处理。
如果都不满足,将返回容器级别的404,可在web.xml中配置404页。*
此处的404不受JFinal配置的404页控制。
静态资源进入到ActionHandler
时会被直接跳出,执行同上。请求不会到达Action。(示例代码:JFinal/ActionHandler.java)
if (target.indexOf('.') != -1) {
return ;
}
② 请求已经在Handler
完成了该有的使命。在Handler执行了render或者在response中返回了我们想要的数据。
该请求也不会到达Action,这里设置isHandled[0] = true;
请求到此为止,也不会去执行后面的Filter。(示例代码:jnode/XmlHandler.java)
if (target.endsWith(".xml")) {
String view = target.replace(".xml", ".vm");
RenderFactory.me().getRender("/xml".concat(view)).setContext(request, response).render();
// 跳出
isHandled[0] = true;
return;
}
③ 酒肉穿肠过,佛祖心中留。请求会依次经过各个Handler,抵达Action。
nextHandler.handle(target, request, response, isHandled);
参考
jfinal处理请求的流程问题:http://www.oschina.net/question/1047244_132206
推荐
JFinal2.0极速开发视频教程:http://blog.dreamlu.net/blog/79
如梦技术JFinalQQ交流群:237587118