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的实现类


 

 

③Hander接口有多个实现类,我们分析ActionHandler的handler()方法

 

/**
	 * 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()方法进行渲染
		}
		catch (RenderException e) {
			if (log.isErrorEnabled()) {
				String qs = request.getQueryString();
				log.error(qs == null ? target : target + "?" + qs, e);
			}
		}
		catch (ActionException e) {

 

Render的实现类


 

 

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

/**
	 * 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);
			}
			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);
			}
	}

 

猜你喜欢

转载自18211103738.iteye.com/blog/2154263