JFinal教程1——小白的第一個JFinal程序

g4mm 9年前發布 | 980K 次閱讀 JFinal Web框架

1. JFinal簡介 

JFinal 是 基于 Java 語言的極速 WEB + ORM 框架,其核心設計目標是開發迅速、代碼量少、學習簡單、功能強大、輕量級、易擴展、Restful。在 擁有Java語言所有優勢的同時再擁有ruby、python、php等動態語言的開發效率!為您節約更多時間,去陪戀人、家人和朋友 :)

 

JFinal 官方網站:http://www.jfinal.com

JFinal有如下主要特點:

  • MVC架構,設計精巧,使用簡單

    </li>

  • 遵循COC原則,零配置,無xml

    </li>

  • 獨創Db + Record模式,靈活便利

    </li>

  • ActiveRecord支持,使數據庫開發極致快速

    </li>

  • 自動加載修改后的java文件,開發過程中無需重啟web server

    </li>

  • AOP支持,攔截器配置靈活,功能強大

    </li>

  • Plugin體系結構,擴展性強

    </li>

  • 多視圖支持,支持FreeMarker、JSP、Velocity

    </li>

  • 強大的Validator后端校驗功能

    </li>

  • 功能齊全,擁有struts2的絕大部分功能

    </li>

  • 體積小僅218K,且無第三方依賴

    </li> </ul>

     

    截至筆者撰寫此文時,JFinal已經發布到了1.6版本。

     

    2. 小白的第一個JFinal程序

    為了使小白能夠完全的按步驟創建第一個JFinal應用并運行,筆者將以Java界最流行的Eclipse平臺為例,搭建出所有基礎教程中喜歡的Hello world應用。

    2.1. Eclipse平臺搭建

    2.1.1. 下載Eclipse

    搭建Web應用,首選Eclipse JEE版本,請到圖所示的地址下載相應版本。

    JFinal教程1——小白的第一個JFinal程序 

    至于JDK的安裝,這里就不再說明了,本文面向的是JFinal小白,而不是李太白^_^

    解壓并運行Eclipse,你將看到下面的畫面:

    JFinal教程1——小白的第一個JFinal程序 

     

    如果彈出下面的畫面(多在內存小或Windows XP中出現),則需要修改eclipse.ini中的參數:

    JFinal教程1——小白的第一個JFinal程序 

     

    修改如下參數即可,如果還是不行,請查詢百度:.

    -startup

    plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar

    --launcher.library

    plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200.v20140116-2212

    -product

    org.eclipse.epp.package.jee.product

    --launcher.defaultAction

    openFile

    --launcher.XXMaxPermSize

    256M  -- 改為192或更小

    -showsplash

    org.eclipse.platform

    --launcher.XXMaxPermSize

    256m  -- 優先修改此參數,改為192或更小

    --launcher.defaultAction

    openFile

    --launcher.appendVmargs

    -vmargs

    -Dosgi.requiredJavaVersion=1.6

    -Xms40m

    -Xmx512m

    </td> </tr> </tbody> </table>

     

    2.1.2. 配置Tomcat

    雖然JFinal自帶的Demo運行在Jetty下,但本文還是選擇以TomcatWeb容器做說明,已經知道如何設置Tomcat的小白可跳過此節。

    運行Tomcat,打開菜單Windows-->Perferences,在彈出的窗口中按下圖選擇:

    JFinal教程1——小白的第一個JFinal程序 

     

    選擇習慣使用的Tomcat V6

    JFinal教程1——小白的第一個JFinal程序 

     

    沒必要追求最新版本,在線安裝Eclipse推薦的Tomcat 6.0.37版本即可:

    JFinal教程1——小白的第一個JFinal程序 

     

    彈出License說明,直接點Finish即可:

    JFinal教程1——小白的第一個JFinal程序 

     

    下載完成后會讓你指定Tomcat存放的文件夾:

     

     

    JFinal教程1——小白的第一個JFinal程序 

     

    再次回到設置頁面,點Finish

    JFinal教程1——小白的第一個JFinal程序 

     

    至此,Tomcat搭建完成:

    JFinal教程1——小白的第一個JFinal程序 

     

    2.2. 創建Web應用

    2.2.1. 新建Dynamic Web工程

    在創建工程之前,先打開菜單Windows-->Perferences,在彈出的窗口中修改默認字符集:

    JFinal教程1——小白的第一個JFinal程序 

     

    Eclipse的工具欄上可直接創建Dynamic Web工程:

    JFinal教程1——小白的第一個JFinal程序 

     

    彈出新建窗口,輸入新工程名MyJFinalApp,直接點Finish

    JFinal教程1——小白的第一個JFinal程序 

     

    至此,Dynamic Web工程創建完成:

    JFinal教程1——小白的第一個JFinal程序 

     

    在工程的屬性中可以看到,Web應用相關的Library已經默認包含:

    JFinal教程1——小白的第一個JFinal程序 

     

    2.2.2. 下載JFinal

    既然基于JFinal框架,沒有理由不下載JFinal相關Jar包。打開JFinal官方網站http://www.jfinal.com/,下載相關內容:

    JFinal教程1——小白的第一個JFinal程序 

     

    下載jfinal-1.6-bin-with-src.jar是為了使小白在使用中可方便地查看并分析源碼,下載jfinal-1.6_demo_for_jsp.zip是因為有部分必要的Jar包在Demo中可以找到,而且,第一個Demo將采用JSP頁面。

    將下載好的jfinal-1.6-bin-with-src.jar直接Copy到工程的下圖位置:

    JFinal教程1——小白的第一個JFinal程序 

     

    2.3. 配置及編碼

    這一章節比較重要,介紹如何配置及編碼,完成第一個JFinal應用。

     

    2.3.1. 創建MyAppConfig.java

    首先創建MyJFinal的配置類MyAppConfig.java

    JFinal教程1——小白的第一個JFinal程序 

     

    在方法中添加如下代碼:

    sesese色

    @Override

    public void configConstant(Constants me) {

    me.setDevMode(true);

    me.setEncoding("utf-8");

    me.setViewType(ViewType.JSP);

    }

     

    @Override

    public void configHandler(Handlers me) {

    me.add(new ContextPathHandler("basePath"));

    }

    </td> </tr> </tbody> </table>

     

    2.3.2. 修改web.xml

    既然MyAppConfig.java是入口,那么,在Tomcat這個容器中,就需要配置這個入口,使得Tomcat啟動的同時加載這個入口類。

    打開web.xml,追加內容:

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns="http://java.sun.com/xml/ns/javaee"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

    id="WebApp_ID" version="2.5">

    <display-name>MyJFinalApp</display-name>

    <welcome-file-list>

    <welcome-file>index.html</welcome-file>

    <welcome-file>index.htm</welcome-file>

    <welcome-file>index.jsp</welcome-file>

    <welcome-file>default.html</welcome-file>

    <welcome-file>default.htm</welcome-file>

    <welcome-file>default.jsp</welcome-file>

    </welcome-file-list>

     

    <filter>

    <filter-name>jfinal</filter-name>

    <filter-class>com.jfinal.core.JFinalFilter</filter-class>

    <init-param>

    <param-name>configClass</param-name>

    <param-value>cn.myapp.config.MyAppConfig</param-value>

    </init-param>

    </filter>

     

    <filter-mapping>

    <filter-name>jfinal</filter-name>

    <url-pattern>/*</url-pattern>

    </filter-mapping>

    </web-app>

    </td> </tr> </tbody> </table>

     

     

    2.3.3. 創建JSP頁面文件

    在創建JSP頁面之前先修改一下JSP文件的默認字符集。如下圖所示,打開菜單Windows-->Perferences,在彈出的窗口中修改默認字符集為utf-8即可:

    JFinal教程1——小白的第一個JFinal程序 

     

    通過右建,在WebContentnew一個新的jsp文件:

    JFinal教程1——小白的第一個JFinal程序 

     

    文件名為index.jsp,并放入WebContent中:

    JFinal教程1——小白的第一個JFinal程序 

     

    完成后可看到首先要打開的index.jsp已經有默認內容了,并且字符集為utf-8

    <%@ page language="java" contentType="text/html; charset=UTF-8"

        pageEncoding="UTF-8"%>

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    <title>Insert title here</title>

    </head>

    <body>

     

    </body>

    </html>

    </td> </tr> </tbody> </table>

     

    并在JSP文件的<body>標簽中追加如下代碼:

  • <body>

    <form action="${basePath}/sayHello" method="post">

    請輸入您的名字:

    <input type="text" name="userName" />

    <input type="submit" value="確定"/>

    </form>

    </body>

    </td> </tr> </tbody> </table>

     

     

    同樣的步驟,再創建一個hello.jsp,并在<body>標簽中追加如下代碼:

  • <body>

    <p>${sayHello}</p><p><a href="${basePath}/"></a></p>

    </body>

    </td> </tr> </tbody> </table>

     

    2.3.4. 創建Controller

    創建IndexController.java用于響應頁面請求,如下圖:

    JFinal教程1——小白的第一個JFinal程序 

     

    并添加代碼:

  • public class IndexController extends Controller {

     

    public void index(){

    this.render("/index.jsp");

    }

    public void sayHello(){

    String userName = this.getAttr("userName");

    String sayHello = "Hello " + userName + ",welcome to JFinal world.";

    this.setAttr("sayHello", sayHello);

    this.render("/hello.jsp");

    }

    }

    </td> </tr> </tbody> </table>

     

    2.3.5. 注冊Controller路由

    JSP頁面和Controller都準備完成后,就需要在MyAppConfig.java中將兩者關聯起來,JFinal里稱之為Route(路由),下面是MyAppConfig類中追加的路由代碼:

    @Override

    public void configRoute(Routes me) {

    me.add("/", IndexController.class);

    }

    </td> </tr> </tbody> </table>

     

    2.4. 發布、運行與調試

    2.4.1. 發布

    上面所有工作完成后,則需要將App發布到Tomcat。在Eclipse IDE的底部,找到Servers,并點擊下圖中標記的區域創建Tomcat實例(前面的Tomcat配置只是配置Eclipse中的Tomcat插件,這里需要建立Tomcat實例。實例可配置多個,但端口不能沖突):

    JFinal教程1——小白的第一個JFinal程序 

     

    在彈出的對話框中做如下配置:

    JFinal教程1——小白的第一個JFinal程序 

    MyJFinalApp加入到新建的Tomcat實例后點Finish

    JFinal教程1——小白的第一個JFinal程序 

     

    2.4.2. 運行

    選擇新建的Tomcat實例,并以Debug方式啟動:

    JFinal教程1——小白的第一個JFinal程序 

    啟動正常的話,可在控制臺下看到啟動信息:

    JFinal教程1——小白的第一個JFinal程序 

     

    打開瀏覽器,并輸入URLhttp://localhost:8080/MyJFinalApp/,應該可看到如下畫面:

    JFinal教程1——小白的第一個JFinal程序 

     

    小白們,感動吧,終于將JFinal環境搭建起來了。

    在輸入框中輸入“小白”,點擊確定,出現下面的畫面:

    JFinal教程1——小白的第一個JFinal程序 

     

    2.4.3. 調試

    很明顯,頁面中出現了錯誤,紅框中標識的內容是null,而不是期待的小白”。

    再看看控制臺的輸出:

    JFinal教程1——小白的第一個JFinal程序 

    在頁面中輸入的字串正確地傳給了后臺IndexController.sayHello()方法,那么,為什么沒有顯示出來呢?請小白在IndexController.sayHello()中追加斷點:

    JFinal教程1——小白的第一個JFinal程序 

     

    然后再次打開URLhttp://localhost:8080/MyJFinalApp/,在輸入框中輸入“小白”,點擊確定。這時,Eclipse進入調試模式。通過調試查看userName取得的值為null

    JFinal教程1——小白的第一個JFinal程序 

     

    仔細分析發生錯誤的這行代碼,或直接查看此方法的源碼,原來,getArrt("userName")方法取到的是HttpServletRequest中的屬性,而不是請求參數。應該改成從取參數的getPara("userName")方法:

  • public void sayHello(){

    String userName = this.getPara("userName");

    。。。。。。

    </td> </tr> </tbody> </table>

     

    又一次打開URhttp://localhost:8080/MyJFinalApp/,在輸入框中輸入“小白”,點擊確定,終于出現了令人期待的結果:

    JFinal教程1——小白的第一個JFinal程序 

     

    2.5. 為小白解惑

    實際上,除去EclipseTomcat的準備以外,配置及編碼那塊在熟練的人手里只需要10分鐘左右,當之無愧的極速WEB開發。當然,前面只是使用到了JFinalWEB框架,ORM框架在后面的教程中會介紹到。

    這一章節,將粗略地講解一下JFinalWEB部分是如何搭載在Tomcat容器中,啟動并響應用戶操作的過程。

    另外,推薦小白們看完此章節后研究下張劍峰同學寫的《JFinal技術架構淺析》一文。

     

    2.5.1. JFinal啟動

    前面,小白們創建MyAppConfig.java,同時修改web.xml。這就為啟動JFinal做好了準備,下面我們就來分析下Tomcat啟動的同時是怎么初始化MyJFinalApp的。

    先來看web.xml

  • <filter>

    <filter-name>jfinal</filter-name>

    <filter-class>com.jfinal.core.JFinalFilter</filter-class>

    <init-param>

    <param-name>configClass</param-name>

    <param-value>cn.myapp.config.MyAppConfig</param-value>

    </init-param>

    </filter>

     

    <filter-mapping>

    <filter-name>jfinal</filter-name>

    <url-pattern>/*</url-pattern>

    </filter-mapping>

    </td> </tr> </tbody> </table>

    xml中首先聲明了<filter>,它是JFinalFilter,同時定義了<init-param>,指向應用程序的配置類MyAppConfig.java

    <filter-mapping>中,定義了<url-pattern>為“/*”,也就是說,此Web應用所有的URL都將將由JFinalFilter這個過濾器來處理。

    Tomcat啟動過程:

    JFinal教程1——小白的第一個JFinal程序 

    過程中,對于JFinal開發人員來說,最有用操作就是“調用MyAppConfig各方法”,也就是執行了如下代碼:

    @Override

    public void configConstant(Constants me) {

    me.setDevMode(true);

    me.setEncoding("utf-8");

    me.setViewType(ViewType.JSP);

    }

     

    @Override

    public void configHandler(Handlers me) {

    me.add(new ContextPathHandler("basePath"));

    }

     

    @Override

    public void configRoute(Routes me) {

    me.add("/", IndexController.class);

    }

    </td> </tr> </tbody> </table>

    各方法的作用請參考《JFinal-手冊-1.5.pdf》,此處不再復述手冊可從官網http://www.jfinal.com/下載。

    2.5.2. 響應用戶操作

    應用中,創建了兩個JSP頁面,分別是“index.jsp”和“hello.jsp”,在瀏覽器中訪問http://localhost:8080/MyJFinalApp/時明顯打開了index.jsp頁面。經歷過SSHSpringMVC的小白應該會很奇怪,明明沒有像SpringMVC那樣用注解聲明Controller,也沒有在注解方法對應的URL,而JFinal卻正確地打開了index.jsp

    首先請看MyAppConfig.configRoute()方法中的URL路由代碼:

    me.add("/", IndexController.class);

    </td> </tr> </tbody> </table>

    這句代碼實際上已經配置了URLController之間的對應關系,第一個參數"/"就是指的根。當用戶訪問根URL時,依據約定JFinal會將其路由到IndexController.index()方法。

    那么,在訪問http://localhost:8080/MyJFinalApp/時,JFinal如何知道訪問的是"/"()呢?

    首先請小白雙擊Tomcat配置項:

    JFinal教程1——小白的第一個JFinal程序 

    在彈出的Tomcat實例屬性窗口中找到Ports選項:

    JFinal教程1——小白的第一個JFinal程序 

    這里說明Tomcat實例使用的是8080端口,也就是通過http://localhost:8080可訪問此Tomcat

     

    然后請小白打開部署的Tomcat實例的server.xml

    JFinal教程1——小白的第一個JFinal程序 

    server.xml底部,我們可以發現MyJFinalApp的配置:

    <Context docBase="MyJFinalApp" path="/MyJFinalApp" reloadable="true" source="org.eclipse.jst.jee.server:MyJFinalApp"/>

    </td> </tr> </tbody> </table>

    請看path參數,它的值為"/MyJFinalApp"(一定要和前面Context root配置一樣),說明此應用部署到Tomcat的后使用的根URL為“http://localhost:8080/MyJFinalApp” http://localhost:8080/MyJFinalApp”。

    提示:修改reloadable的值為false,在調試狀態,修改MyJFinalApp的代碼時Tomcat不會頻繁重新加載應用,節省開發調試時間。

     

    通過上面,我們已經知道,通過訪問http://localhost:8080/MyJFinalApp/JFinal會將其路由到IndexController.index()方法,為什么是index()方法?其實這是一個約定,具體的約定請參考JFinal-手冊-1.5.pdf

    那么它是如何打開index.jsp文件的呢?我們來查看index()方法的代碼:

  • public class IndexController extends Controller {

    public void index(){

    this.render("/index.jsp");

    }

    。。。。。。

    </td> </tr> </tbody> </table>

    只有一句代碼,作用是渲染\WebContent\index.jsp這個文件后返回給瀏覽器。小白們又糊涂了,為什么不return一個字串來指定渲染頁面呀?這里就是JFinal設計者的聰明之處了,渲染頁面可能不止常見的JSPFREE_MARKERVELOCITY等幾種類型,隨著技術的發展,模板頁面類型會層出不窮。JFinal中,只需要擴展Render就可輕松支持,贊呀^_^

    打開index.jsp后,用戶在頁面中輸入名字,然后點擊確定,這里調用的是如下action代碼:

    <form action="${basePath}/sayHello" method="post">

    請輸入您的名字:

    <input type="text" name="userName" />

    <input type="submit" value="確定"/>

    </form>

    </td> </tr> </tbody> </table>

    action的值為"${basePath}/sayHello",那么${basePath}是什么東東呢?有點JSP基礎的人都知道,basePath必須設置到HttpServletRequest中才能在頁面中使用。那么又是什么時候設置進去的呢?請注意前面創建MyAppConfig.java中的一段代碼:

  • @Override

    public void configHandler(Handlers me) {

    me.add(new ContextPathHandler("basePath"));

    }

    </td> </tr> </tbody> </table>

    在這里配置了一個ContextPathHandler,構造參數是"basePath",難道它們有聯系!沒錯,小白們可直接查看此Handler的源碼就可以發現,一行代碼已經做必須的事情:

    public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {

    request.setAttribute(contextPathName, request.getContextPath());

    nextHandler.handle(target, request, response, isHandled);

    }

    </td> </tr> </tbody> </table>

    ContextPathHandler就只做了這么一件事情,就是在每次(注意是每次)請求時將Context Path(此應用中的值為"/MyJFinalApp")設置到HttpServletRequest的屬性"basePath"中,這樣,頁面就可以使用了。

    為了證實這一點,可在瀏覽器中打開index.jsp返回的html源碼:

    JFinal教程1——小白的第一個JFinal程序 

    此頁面中,點擊確定,就將用戶輸入的userName,通過Post方式調用http://localhost:8080/MyJFinalApp/sayHello地址。最終,調用的是IndexController.sayHello()方法。

    JFinal是怎么知道調用的是此方法呢?其實很簡單,在JFinal的路由規則中,首先會去匹配地址/sayHello。顯然是找不到的,因為在MyAppConfig.configRoute()方法中根本就沒有配置與/sayHello對應的Controller。所以JFinal會截掉最后一個/后的內容再次匹配,/sayHello截取掉后就成了/,也就匹配到了IndexController。根據約定,被截取的內容sayHello應該是方法名,所以,也順序定位到了IndexController.sayHello()方法。

    小白們,明白了吧,JFianl的路由約定拋棄掉了繁瑣的注解,這就是一種簡潔美。這種設計在JFianl中處處都存在,隨著對JFinal了解的加深,大家會慢慢體會到約定大于配置不單單是一句口號。

    有部分人也提出了質疑:注解能規范編碼,一目了然……等等。但如果回過頭來想,注解實際上也就是一種顯示的約定而已,而JFianl將其當成了隱式約定。使用注解功能更強了點嗎?答案是沒有,SSHSpringMVC的這類注解與JFinal的實際提供的路由在功能上沒有任何區別,沒有脫離Servlet的范疇。

    提供源碼:小白的第一個JFinal程序.zip

    來自:http://my.oschina.net/u/1175852/blog/261235

     本文由用戶 g4mm 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!