JFinal 入門

1. 建立MyAppConfig.java

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

在方法中添加以下代碼:java

@Overrideweb

public void configConstant(Constants me) {瀏覽器

me.setDevMode(true);架構

me.setEncoding("utf-8");app

me.setViewType(ViewType.JSP);框架

}eclipse

 

@Overridejsp

public void configHandler(Handlers me) {ide

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

}

 

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>

 

 

3. 建立JSP頁面文件

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

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

<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>

 

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

}

}

 

5. 註冊Controller路由

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

@Override

public void configRoute(Routes me) {

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

}

 

2. 發佈、運行與調試

2.1. 發佈

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

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

 

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

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

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

 

 調試

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

再看看控制檯的輸出:

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

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

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

 

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

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

 

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

public void sayHello(){

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

。。。。。。

 

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

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

 

爲小白解惑

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

這一章節,將粗略地講解一下JFinal的WEB部分是如何搭載在Tomcat容器中,啓動並響應用戶操做的過程。

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

 

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教程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);

}

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

響應用戶操做

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

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

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

這句代碼實際上已經配置了URL與Controller之間的對應關係,第一個參數"/"就是指的根。當用戶訪問根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"/>

請看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設計者的聰明之處了,渲染頁面可能不止常見的JSP、FREE_MARKER、VELOCITY等幾種類型,隨着技術的發展,模板頁面類型會層出不窮。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源碼:

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將其當成了隱式約定。使用註解功能更強了點嗎?答案是沒有,SSH和SpringMVC的這類註解與JFinal的實際提供的路由在功能上沒有任何區別,沒有脫離Servlet的範疇。

 

 

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

相關文章
相關標籤/搜索