您的位置:首页 > 其它

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

2014-05-19 00:00 639 查看
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{
@Override
public 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) {//请求没有找到对应的处理类,返回404
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();//返回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.");
else
handle(actionUrl, request, response, isHandled);//处理ActionRender.getActionUrl
return ;
}

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

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息