路由的使用
實現JfinalConfig,重寫configRoute()方法:
public void configRoute(Routes routes) {
routes.add("/hello", DemoController.class,"");
}
第一個參數是controllerKey,第二個是自己寫的Controller類,第三個是webApp下的視圖路徑.
路由的源碼實現
configRoute(Routes routes)方法在Config類中別調用.具體如下:
class Config {
static void configJFinal(JFinalConfig jfinalConfig) {
...
jfinalConfig.configRoute(routes);
...
}
public static final Routes getRoutes() {
return routes;
}
}
可以看到Config 類中提供了一個getRoutes()方法,我們看看在Jfinal類中調用這個方法,如下:
public final class JFinal {
private void initActionMapping() {
this.actionMapping = new ActionMapping(Config.getRoutes());
this.actionMapping.buildActionMapping();
Config.getRoutes().clear();
}
}
然後在buildActionMapping方法中使route.getFinalViewPath(routes.getBaseViewPath())添加到Action中去了:
protected void buildActionMapping() {
...
Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, route.getFinalViewPath(routes.getBaseViewPath()));
//添加到mapping中
if (this.mapping.put(actionKey, action) != null) {
throw new RuntimeException(this.buildMsg(actionKey, controllerClass, method));
}
...
這邊封裝好actionmapping在ActionHanle類中handle()方法中會調用
Action action = this.actionMapping.getAction(target, urlPara)獲取action.具體如下:
public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
if (target.indexOf(46) == -1) {
isHandled[0] = true;
String[] urlPara = new String[]{null};
Action action = this.actionMapping.getAction(target, urlPara);
//action爲null反回404
if (action == null) {
if (log.isWarnEnabled()) {
String qs = request.getQueryString();
log.warn("404 Action Not Found: " + (qs == null ? target : target + "?" + qs));
}
renderManager.getRenderFactory().getErrorRender(404).setContext(request, response).render();
} else {
Controller controller = null;
try {
String actionUrl;
try {
controller = this.controllerFactory.getController(action.getControllerClass());
controller.init(action, request, response, urlPara[0]);
if (this.devMode) {
if (ActionReporter.isReportAfterInvocation(request)) {
(new Invocation(action, controller)).invoke();
ActionReporter.report(target, controller, action);
} else {
ActionReporter.report(target, controller, action);
(new Invocation(action, controller)).invoke();
}
} else {
(new Invocation(action, controller)).invoke();
}
Render render = controller.getRender();
if (!(render instanceof ForwardActionRender)) {
if (render == null) {
//action.getViewPath() 獲取設定的viewpath到指定路徑上
render = renderManager.getRenderFactory().getDefaultRender(action.getViewPath() + action.getMethodName());
}
render.setContext(request, response, action.getViewPath()).render();
return;
}
actionUrl = ((ForwardActionRender)render).getActionUrl();
if (target.equals(actionUrl)) {
throw new RuntimeException("The forward action url is the same as before.");
}
this.handle(actionUrl, request, response, isHandled);
} catch (RenderException var17) {
if (log.isErrorEnabled()) {
actionUrl = request.getQueryString();
log.error(actionUrl == null ? target : target + "?" + actionUrl, var17);
}
return;
} catch (ActionException var18) {
int errorCode = var18.getErrorCode();
String msg = null;
if (errorCode == 404) {
msg = "404 Not Found: ";
} else if (errorCode == 401) {
msg = "401 Unauthorized: ";
} else if (errorCode == 403) {
msg = "403 Forbidden: ";
}
String qs;
if (msg != null) {
if (log.isWarnEnabled()) {
qs = request.getQueryString();
log.warn(msg + (qs == null ? target : target + "?" + qs));
}
} else if (log.isErrorEnabled()) {
qs = request.getQueryString();
log.error(qs == null ? target : target + "?" + qs, var18);
}
var18.getErrorRender().setContext(request, response, action.getViewPath()).render();
return;
} catch (Exception var19) {
if (log.isErrorEnabled()) {
actionUrl = request.getQueryString();
log.error(actionUrl == null ? target : target + "?" + actionUrl, var19);
}
renderManager.getRenderFactory().getErrorRender(500).setContext(request, response, action.getViewPath()).render();
return;
}
} finally {
if (controller != null) {
controller.clear();
}
}
}
}
}
render.setContext()中的源碼:
public Render setContext(HttpServletRequest request, HttpServletResponse response, String viewPath) {
this.request = request;
this.response = response;
if (this.view != null && this.view.length() > 0 && this.view.charAt(0) != '/') {
this.view = viewPath + this.view;
}
return this;
}