JFinalConfig

概述

    基於JFinal的web項目須要建立一個繼承自JFinalConfig類的子類,該類用於對整個web項目進行配置。html

    JFinalConfig子類須要實現六個抽象方法,以下所示:前端

  1. public class DemoConfig extends JFinalConfig {
  2.     public void configConstant(Constants me) {}
  3.     public void configRoute(Routes me) {}
  4.     public void configEngine(Engine me) {}
  5.     public void configPlugin(Plugins me) {}
  6.     public void configInterceptor(Interceptors me) {}
  7.     public void configHandler(Handlers me) {}
  8. }

2.2 configConstant(..)

    此方法用來配置JFinal常量值,如開發模式常量devMode的配置,以下代碼配置了JFinal運行在開發模式:java

  1. public void configConstant(Constants me) {
  2.     me.setDevMode(true);
  3. }

    在開發模式下,JFinal會對每次請求輸出報告,如輸出本次請求的URL、Controller、Method以及請求所攜帶的參數。git

 

2.3 configRoute(..)

一、經常使用配置

    此方法用來配置訪問路由,以下代碼配置了將 "/hello" 映射到HelloController這個控制器,經過如下的配置,http://localhost/hello  將訪問 HelloController.index() 方法,而http://localhost/hello/methodName  將訪問到 HelloController.methodName() 方法。web

  1. public void configRoute(Routes me) {
  2.     // 若是要將控制器超類中的 public 方法映射爲 action 配置成 true,通常不用配置
  3.     me.setMappingSuperClass(false);
  4.     
  5.     me.setBaseViewPath("/view");
  6.     me.addInterceptor(new FrontInterceptor());
  7.     me.add("/hello", HelloController.class);
  8. }

 

    Routes.setBaseViewPath(baseViewPath) 方法用於爲該 Routes 內部的全部 Controller 設置視圖渲染時的基礎路徑,該基礎路徑與Routes.add(…, viewPath) 方法傳入的viewPath以及 Controller.render(view) 方法傳入的 view 參數聯合組成最終的視圖路徑,規則以下:redis

    finalView = baseViewPath + viewPath + view數據庫

    注意:當view以 「/」 字符打頭時表示絕對路徑,baseViewPath 與 viewPath 將被忽略。後端

 

二、路由配置 API

    Routes 類中添加路由的方法有兩個:緩存

  1. public Routes add(String controllerKey, Class<? extends Controller> controllerClass, String viewPath)
  2. public Routes add(String controllerKey, Class<? extends Controller> controllerClass)

    第一個參數 controllerKey 是指訪問某個 Controller 所須要的一個字符串,該字符串惟一對應一個 Controller,controllerKey僅能定位到Controller。安全

    第二個參數 controllerClass 是該 controllerKey 所對應到的 Controller 。

    第三個參數viewPath是指該Controller返回的視圖的相對路徑(該參數具體細節將在Controller相關章節中給出)。當viewPath未指定時默認值爲controllerKey。

    jfinal 3.6 新增了一個配置方法:setMappingSuperClass(boolean),默認值爲 false。配置成爲 true 時,你的 controller 的超類中的 public 方法也將會映射成 action。若是你的項目中使用了 jfinal weixin 項目的 MsgController,則須要將其配置成 true,由於 MsgController 中的 index() 須要被映射成 action 才能正常分發微信服務端的消息。

 

三、極簡路由規則

    JFinal 僅有四種路由,路由規則以下表:

8.png

    從表中能夠看出,JFinal訪問一個確切的Action(Action定義見3.2節)須要使用controllerKey與method來精肯定位,當method省略時默認值爲index。

    urlPara是爲了能在url中攜帶參數值,urlPara能夠在一次請求中同時攜帶多個值,JFinal默認使用減號「-」來分隔多個值(可經過constants. setUrlParaSeparator(String)設置分隔符),在Controller中能夠經過getPara(int index)分別取出這些值。controllerKey、method、urlPara這三部分必須使用正斜槓「/」分隔。

    注意,controllerKey自身也能夠包含正斜槓「/」,如「/admin/article」,這樣實質上實現了struts2的namespace功能。

    JFinal在以上路由規則以外還提供了ActionKey註解,能夠打破原有規則,如下是代碼示例:

  1. public class UserController extends Controller {
  2.     @ActionKey("/login")
  3.     public void login() {
  4.        render("login.html");
  5.     }
  6. }

    假定 UserController 的 controllerKey值爲「/user」,在使用了@ActionKey(「/login」)註解之後,actionKey由原來的「/user/login」變爲了「/login」。該註解還可讓actionKey中使用減號或數字等字符,如「/user/123-456」。

    若是JFinal默認路由規則不能知足需求,開發者還能夠根據須要使用Handler定製更加個性化的路由,大致思路就是在Handler中改變第一個參數String target的值。

 

四、路由拆分、模塊化

    JFinal路由還能夠進行拆分配置,這對大規模團隊開發十分有用,如下是代碼示例:

  1. public class FrontRoutes extends Routes {
  2.     public void config() {
  3.        setBaseViewPath("/view/front");
  4.        add("/", IndexController.class);
  5.        add("/blog", BlogController.class);
  6.     }
  7. }
  1. public class AdminRoutes extends Routes {
  2.     public void config() {
  3.        setBaseViewPath("/view/admin");
  4.        addInterceptor(new AdminInterceptor());
  5.        add("/admin", AdminController.class);
  6.        add("/admin/user", UserController.class);
  7.     }
  8. }
  1. public class MyJFinalConfig extends JFinalConfig {
  2.     public void configRoute(Routes me) {
  3.        me.add(new FrontRoutes());  // 前端路由
  4.        me.add(new AdminRoutes());  // 後端路由
  5.     }
  6.     public void configConstant(Constants me) {}
  7.     public void configEngine(Engine me) {}
  8.     public void configPlugin(Plugins me) {}
  9.     public void configInterceptor(Interceptors me) {}
  10.     public void configHandler(Handlers me) {}
  11. }

    如上三段代碼,FrontRoutes類中配置了系統前端路由,AdminRoutes配置了系統後端路由,MyJFinalConfig.configRoute(…)方法將拆分後的這兩個路由合併起來。使用這種拆分配置不只可讓MyJFinalConfig文件更簡潔,並且有利於大規模團隊開發,避免多人同時修改MyJFinalConfig時的版本衝突。

    FrontRoutes與AdminRoutes中分別使用setBaseViewPath(…)設置了各自Controller.render(view)時使用的baseViewPath。

    AdminRoutes 還經過addInterceptor(new AdminInterceptor())添加了 Routes 級別的攔截器,該攔截器將攔截 AdminRoutes 中添加的全部 Controller,至關於業務層的inject攔截器,會在class攔截器以前被調用。這種用法能夠避免在後臺管理這樣的模塊中的全部class上使用@Before(AdminInterceptor.class),減小代碼冗餘。

 

2.4 configEngine(..)

    此方法用來配置Template Engine,如下是代碼示例:

  1. public void configEngine(Engine me) {
  2.     me.addSharedFunction("/view/common/layout.html");
  3.     me.addSharedFunction("/view/common/paginate.html");
  4.     me.addSharedFunction("/view/admin/common/layout.html");
  5. }

    上面的方法向模板引擎中添加了三個定義了 template function 的模板文件,更詳細的介紹詳見 Template Engine 那一章節的內容。

   此方法用來配置JFinal的Plugin,以下代碼配置了Druid數據庫鏈接池插件與ActiveRecord數據庫訪問插件。經過如下的配置,能夠在應用中使用ActiveRecord很是方便地操做數據庫。

  1. public void configPlugin(Plugins me) {
  2.     DruidPlugin dp = new DruidPlugin(jdbcUrl, userName, password);
  3.     me.add(dp);
  4.     
  5.     ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
  6.     arp.addMapping("user", User.class);
  7.     me.add(arp);
  8. }

    JFinal插件架構是其主要擴展方式之一,能夠方便地建立插件並應用到項目中去。

2.6 configInterceptor(..)

    此方法用來配置JFinal的全局攔截器,全局攔截器將攔截全部 action 請求,除非使用@Clear在Controller中清除,以下代碼配置了名爲AuthInterceptor的攔截器。

  1. public void configInterceptor(Interceptors me) {
  2.     me.add(new AuthInterceptor());
  3. }

    JFinal 的 Interceptor 很是相似於 Struts2,但使用起來更方便,Interceptor 配置粒度分爲 Global、Inject、Class、Method四個層次,其中以上代碼配置粒度爲全局。Inject、Class與Method級的Interceptor配置將在後續章節中詳細介紹。

2.7 configHandler(..)

    此方法用來配置JFinal的Handler,以下代碼配置了名爲ResourceHandler的處理器,Handler能夠接管全部web請求,並對應用擁有徹底的控制權,能夠很方便地實現更高層的功能性擴展。

  1. public void configHandler(Handlers me) {
  2.     me.add(new ResourceHandler());
  3. }

   具體用法能夠參考 jfinal 源碼中給出的幾個功能的官方實現:https://gitee.com/jfinal/jfinal/tree/master/src/main/java/com/jfinal/ext/handler

 

注意:Handler 是全局共享的,因此要注意其中聲明的屬性的線程安全問題

2.8 onStart()、onStop() 回調配置

    在 JFinalConfig 繼承類中能夠添加 onStart() 與 onStop(),JFinal 會在系統啓動完成以後以及系統關閉以前分別回調這兩個方法:

  1. // 系統啓動完成後回調
  2. public void onStart() {
  3. }
  4.  
  5. // 系統關閉以前回調
  6. public void onStop() {
  7. }

     這兩個方法能夠很方便地在項目啓動後與關閉前讓開發者有機會進行額外操做,如在系統啓動後建立調度線程或在系統關閉前寫回緩存。


注意:jfinal 3.6 版本以前這兩個方法名爲:afterJFinalStart() 與 beforeJFinalStop()。爲減小記憶成本、代碼輸入量以及輸入手誤的機率,jfinal 3.6 版本改成了目前更簡短的方法名。老方法名仍然被保留,仍然可使用,方便老項目升級到 jfinal 最新版本。

2.9 PropKit 讀取配置

    PropKit工具類用來讀取外部鍵值對配置文件,PropKit能夠極度方便地在系統任意時空使用,配置文件的格式以下:

  1. userName=james
  2. email=no-reply@jfinal.com
  3. devMode=true

 

    以下是 PropKit 代碼示例:

  1. PropKit.use("config.txt");
  2. String userName = PropKit.get("userName");
  3. String email = PropKit.get("email");
  4.  
  5. // Prop 配合用法
  6. Prop p = PropKit.use("config.txt");
  7. Boolean devMode = p.getBoolean("devMode");

 

    以下是在項目中具體的使用示例:

  1. public class AppConfig extends JFinalConfig {
  2.   public void configConstant(Constants me) {
  3.     // 第一次使用use加載的配置將成爲主配置,能夠經過PropKit.get(...)直接取值
  4.     PropKit.use("a_little_config.txt");
  5.     me.setDevMode(PropKit.getBoolean("devMode"));
  6.   }
  7.  
  8.   public void configPlugin(Plugins me) {
  9.     // 非第一次使用use加載的配置,須要經過每次使用use來指定配置文件名再來取值
  10.     String redisHost = PropKit.use("redis_config.txt").get("host");
  11.     int redisPort = PropKit.use("redis_config.txt").getInt("port");
  12.     RedisPlugin rp = new RedisPlugin("myRedis", redisHost, redisPort);
  13.     me.add(rp);
  14.  
  15.     // 非第一次使用 use加載的配置,也能夠先獲得一個Prop對象,再經過該對象來獲取值
  16.     Prop p = PropKit.use("db_config.txt");
  17.     DruidPlugin dp = new DruidPlugin(p.get("jdbcUrl"), p.get("user")…);
  18.     me.add(dp);
  19.   }
  20. }

    如上代碼所示,PropKit可同時加載多個配置文件,第一個被加載的配置文件可使用PorpKit.get(…)方法直接操做,非第一個被加載的配置文件則須要使用PropKit.use(…).get(…)來操做。

    PropKit 的使用並不限於在 YourJFinalConfig 中,能夠在項目的任何地方使用。此外PropKit.use(…)方法在加載配置文件內容之後會將數據緩存在內存之中,能夠經過PropKit.useless(…)將緩存的內容進行清除。 

相關文章
相關標籤/搜索