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


1. JFinal簡介 

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

 

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

JFinal有以下主要特色:java

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

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

  • 首創Db + Record模式,靈活便利數據庫

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

  • 自動加載修改後的java文件,開發過程當中無需重啓web server瀏覽器

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

  • Plugin體系結構,擴展性強架構

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

  • 強大的Validator後端校驗功能

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

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

 

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

 

2. 小白的第一個JFinal程序

爲了使小白可以徹底的按步驟建立第一個JFinal應用並運行,筆者將以Java界最流行的Eclipse平臺爲例,搭建出全部基礎教程中喜歡的Hello world應用。

2.1. Eclipse平臺搭建

2.1.1. 下載Eclipse

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

 

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

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

 

 

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

 

 

修改以下參數便可,若是仍是不行,請查詢百度:.

-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

 

2.1.2. 配置Tomcat

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

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

 

 

選擇習慣使用的Tomcat V6

 

 

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

 

 

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

 

 

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

 

 

 

 

再次回到設置頁面,點Finish

 

 

至此,Tomcat搭建完成:

 

 

2.2. 建立Web應用

2.2.1. 新建Dynamic Web工程

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

 

 

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

 

 

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

 

 

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

 

 

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

 

 

2.2.2. 下載JFinal

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

 

 

下載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到工程的下圖位置:

 

 

2.3. 配置及編碼

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

 

2.3.1. 建立MyAppConfig.java

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

 

 

在方法中添加以下代碼:

@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"));

}

 

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>

 

 

2.3.3. 建立JSP頁面文件

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

 

 

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

 

 

文件名爲index.jsp,並放入WebContent中:

 

 

完成後可看到首先要打開的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>

 

並在JSP文件的<body>標籤中追加以下代碼:

<body>

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

請輸入您的名字:

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

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

</form>

</body>

 

 

一樣的步驟,再建立一個hello.jsp,並在<body>標籤中追加以下代碼:

<body>

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

</body>

 

2.3.4. 建立Controller

建立IndexController.java用於響應頁面請求,以下圖:

 

 

並添加代碼:

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

}

}

 

2.3.5. 註冊Controller路由

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

@Override

public void configRoute(Routes me) {

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

}

 

2.4. 發佈、運行與調試

2.4.1. 發佈

上面全部工做完成後,則須要將App發佈到Tomcat。在Eclipse IDE的底部,找到Servers,並點擊下圖中標記的區域建立Tomcat實例(前面的Tomcat配置只是配置Eclipse中的Tomcat插件,這裏須要創建Tomcat實例。實例可配置多個,但端口不能衝突):

 

 

在彈出的對話框中作以下配置:

 

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

 

 

2.4.2. 運行

選擇新建的Tomcat實例,並以Debug方式啓動:

 

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

 

 

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

 

 

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

在輸入框中輸入「小白」,點擊肯定,出現下面的畫面:

 

 

2.4.3. 調試

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

再看看控制檯的輸出:

 

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

 

 

而後再次打開URLhttp://localhost:8080/MyJFinalApp/,在輸入框中輸入「小白」,點擊肯定。這時,Eclipse進入調試模式。經過調試查看userName取得的值爲null

 

 

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

public void sayHello(){

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

。。。。。。

 

又一次打開URhttp://localhost:8080/MyJFinalApp/,在輸入框中輸入「小白」,點擊肯定,終於出現了使人期待的結果:

 

 

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>

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

<filter-mapping>中,定義了<url-pattern>爲「/*」,也就是說,此Web應用全部的URL都將將由JFinalFilter這個過濾器來處理。

Tomcat啓動過程:

 

過程當中,對於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);

}

各方法的做用請參考《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);

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

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

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

 

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

 

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

 

而後請小白打開部署的Tomcat實例的server.xml

 

server.xml底部,咱們能夠發現MyJFinalApp的配置:

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

請看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");

}

。。。。。。

只有一句代碼,做用是渲染\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>

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

@Override

public void configHandler(Handlers me) {

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

}

在這裏配置了一個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);

}

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

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

 

此頁面中,點擊肯定,就將用戶輸入的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

相關文章
相關標籤/搜索