JFinal教程1——小白的第一個JFinal程序
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版本,請到圖所示的地址下載相應版本。
至于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
</td> </tr> </tbody> </table>2.1.2. 配置Tomcat
雖然JFinal自帶的Demo運行在Jetty下,但本文還是選擇以Tomcat為Web容器做說明,已經知道如何設置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"));
}
</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即可:
通過右建,在WebContent中new一個新的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>
</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用于響應頁面請求,如下圖:
并添加代碼:
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實例。實例可配置多個,但端口不能沖突):
在彈出的對話框中做如下配置:
將MyJFinalApp加入到新建的Tomcat實例后點Finish:
2.4.2. 運行
選擇新建的Tomcat實例,并以Debug方式啟動:
啟動正常的話,可在控制臺下看到啟動信息:
打開瀏覽器,并輸入URL:http://localhost:8080/MyJFinalApp/,應該可看到如下畫面:
小白們,感動吧,終于將JFinal環境搭建起來了。
在輸入框中輸入“小白”,點擊確定,出現下面的畫面:
2.4.3. 調試
很明顯,頁面中出現了錯誤,紅框中標識的內容是null,而不是期待的“小白”。
再看看控制臺的輸出:
在頁面中輸入的字串正確地傳給了后臺IndexController.sayHello()方法,那么,為什么沒有顯示出來呢?請小白在IndexController.sayHello()中追加斷點:
然后再次打開URL:http://localhost:8080/MyJFinalApp/,在輸入框中輸入“小白”,點擊確定。這時,Eclipse進入調試模式。通過調試查看userName取得的值為null:
仔細分析發生錯誤的這行代碼,或直接查看此方法的源碼,原來,getArrt("userName")方法取到的是HttpServletRequest中的屬性,而不是請求參數。應該改成從取參數的getPara("userName")方法:
public void sayHello(){
String userName = this.getPara("userName");
。。。。。。
</td> </tr> </tbody> </table>又一次打開UR:http://localhost:8080/MyJFinalApp/,在輸入框中輸入“小白”,點擊確定,終于出現了令人期待的結果:
2.5. 為小白解惑
實際上,除去Eclipse和Tomcat的準備以外,配置及編碼那塊在熟練的人手里只需要10分鐘左右,當之無愧的極速WEB開發。當然,前面只是使用到了JFinal的WEB框架,ORM框架在后面的教程中會介紹到。
這一章節,將粗略地講解一下JFinal的WEB部分是如何搭載在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開發人員來說,最有用操作就是“調用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頁面。經歷過SSH或SpringMVC的小白應該會很奇怪,明明沒有像SpringMVC那樣用注解聲明Controller,也沒有在注解方法對應的URL,而JFinal卻正確地打開了index.jsp。
首先請看MyAppConfig.configRoute()方法中的URL路由代碼:
me.add("/", IndexController.class);
</td> </tr> </tbody> </table>這句代碼實際上已經配置了URL與Controller之間的對應關系,第一個參數"/"就是指的根。當用戶訪問根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"/>
</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設計者的聰明之處了,渲染頁面可能不止常見的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>
</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源碼:
此頁面中,點擊確定,就將用戶輸入的”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的范疇。
提供源碼:小白的第一個JFinal程序.zip
來自:http://my.oschina.net/u/1175852/blog/261235本文由用戶 g4mm 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!相關經驗
相關資訊
sesese色