您的位置:首页 > 其它

源码有毒:Jfinal源码解析(六)

2016-08-12 16:42 274 查看
源码有毒:Jfinal源码解析(一)

源码有毒:Jfinal源码解析(二)

源码有毒:Jfinal源码解析(三)

源码有毒:Jfinal源码解析(四)

源码有毒:Jfinal源码解析(五)

继续看Handler.handler方法

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) {
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.init(request, response, urlPara[0]);

if (devMode) {
if (ActionReporter.isReportAfterInvocation(request)) {
new Invocation(action, controller).invoke();
ActionReporter.report(controller, action);
} else {
ActionReporter.report(controller, action);
new Invocation(action, controller).invoke();
}
}
else {
new Invocation(action, controller).invoke();
}

Render render = controller.getRender();
if (render instanceof 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);
return ;
}

if (render == null)
render = renderFactory.getDefaultRender(action.getViewPath() + action.getMethodName());
render.setContext(request, response, action.getViewPath()).render();
}
catch (RenderException e) {
...异常处理
}
}


继续往下走,从actionMapping中获取完Action之后,如果没有获取但相应的Action则返回404错误信息,如果Action存在,则从Action中取出初始化时存储到Action中的Controller的Class然后实例化这个Controller

Controller controller = action.getControllerClass().newInstance();
controller.init(request, response, urlPara[0]);


紧接着创建了ActionInvocation实例,并调用了invoke()方法

new ActionInvocation(action, controller).invoke();


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


在invoke()方法中,显示依次调用了当前action请求对于的拦截器,在所有的拦截器执行完之后,则是调用了具体Action请求对应的Controller中的具体方法

Render render = controller.getRender();
if (render instanceof 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);
return ;
}


如果当前的Action请求是一个重定向请求,则再递归调用handle方法

调用了Render.render()方法,这里看一个简单的例子JsonRender中的render()方法

public void render() {
if (jsonText == null)
buildJsonText();

PrintWriter writer = null;
try {
response.setHeader("Pragma", "no-cache");   // HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);

response.setContentType(forIE ? contentTypeForIE : contentType);
writer = response.getWriter();
writer.write(jsonText);
writer.flush();
} catch (IOException e) {
throw new RenderException(e);
}
finally {
if (writer != null)
writer.close();
}
}


这里代码就比较情切了,把jsonText返回前台调用者,而JsonText在则是把创建JsonRender()对象是传入的数据对象直接转换成了Json字符串

public JsonRender(Object object) {
if (object == null)
throw new IllegalArgumentException("The parameter object can not be null.");
this.jsonText = JsonKit.toJson(object, convertDepth);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JFinal 源码