JFinal处置请求的流程

JFinal处理请求的流程

①从web.xml文件中可以看出jfinal框架本质上是一个Filter

<!DOCTYPE web-app PUBLIC

 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

 "http://java.sun.com/dtd/web-app_2_3.dtd" >

 

<web-app>

<display-name>jfinal</display-name>

  

<filter>

<filter-name>jfinal</filter-name>

<filter-class>com.jfinal.core.JFinalFilter</filter-class>

<init-param>

<param-name>configClass</param-name>

<param-value>com.demo.config.DemoConfig</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>jfinal</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

<welcome-file-list>

<welcome-file>index.html</welcome-file>

</welcome-file-list>

</web-app>

 

JFinalFilter重写了doFilter方法,所有的处理都在该方法中完成

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

 

boolean[] isHandled = {false};

try {

handler.handle(target, request, response, isHandled);

}

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

}

 Handler的实现类

JFinal处置请求的流程
 

 

Hander接口有多个实现类,我们分析ActionHandlerhandler()方法

/**

 * 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);//根据ActionMapping中的映射获取处理当前请求的Action

 

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处理类

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();//调用Controller中相应的处理方法(详见)

}

 

Render render = controller.getRender();//根据Controller中的设置获取数据和视图的对应类Render

if (render instanceof ActionRender) {//如果render是一个ActionRender,则再交给对应的Handler处理

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,则使用默认Render

render = renderFactory.getDefaultRender(action.getViewPath() + action.getMethodName());

render.setContext(request, response, action.getViewPath()).render();//调用Render实现类的render()方法进行渲染

}

 

Render的实现类

JFinal处置请求的流程
 

 

④在ActionInvocationinvoke()方法中,请求先经过一系列拦截器

/**

 * 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(controllerNULL_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);

}

}