您的位置:首页 > 其它

JFinal Handler源码解析——从配置到工作原理

2016-07-20 14:43 495 查看
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 handlerList = new ArrayList();

public Handlers add(Handler handler) {
if (handler != null)
handlerList.add(handler);
return this;
}

public List 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.
*  * 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 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是怎么工作的


Handler->Action,请求到达Handler中之后有三种结局。" title="">

上图描述了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 ;
}


静态资源进入到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);


转发自http://my.oschina.net/qq596392912/blog/504685
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: