为了使小白能够完全的按步骤创建第一个JFinal应用并运行,笔者将以Java界最流行的Eclipse平台为例,搭建出所有基础教程中喜欢的Hello world应用。

1. JFinal简介

JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率!为您节约更多时间,去陪恋人、家人和朋友 :)

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

JFinal有如下主要特点:

  • MVC架构,设计精巧,使用简单

  • 遵循COC原则,零配置,无xml

  • 独创Db + Record模式,灵活便利

  • ActiveRecord支持,使数据库开发极致快速

  • 自动加载修改后的java文件,开发过程中无需重启web server

  • AOP支持,拦截器配置灵活,功能强大

  • 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下,但本文还是选择以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"));

}

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即可:

通过右建,在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>

并在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方式启动:

启动正常的话,可在控制台下看到启动信息:

打开浏览器,并输入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");

。。。。。。

又一次打开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>

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页面。经历过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配置项:

在弹出的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设计者的聪明之处了,渲染页面可能不止常见的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源码:

此页面中,点击确定,就将用户输入的”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?fromerr=7Gyb0PPx

JFinal教程1——小白的第一个JFinal程序的更多相关文章

  1. 纯小白创建第一个Node程序失败-容易忽略的一个细节

    一直觉得自己基础还很差,所以自觉不敢去碰node.js,但又对其心怀好奇.恰巧最近有一点空闲时间,忍不住去试了一下水   这不,在创建第一个node程序时就吃了闭门羹,总是提示我没有定义,如下图, 这 ...

  2. Nhibernate学习教程(2)-- 第一个NHibernate程序

    NHibernate之旅(2):第一个NHibernate程序 本节内容 开始使用NHibernate 1.获取NHibernate 2.建立数据库表 3.创建C#类库项目 4.设计Domain 4- ...

  3. python 教程 第八章、 第一个python程序

    第八章. 第一个python程序 #!/usr/bin/env python import os import sys import time source = [r'G:\s1', r'G:\s2' ...

  4. [Java 教程 03] 我的第一个Java程序

    现在,大家应该都已经安装好jdk环境了吧!是不是已经跃跃欲试,按耐不住心中的小激动了?那我们现在就来写我们java学习生涯中的第一个java程序. 文件相关设置 为了方便后面大家的学习呢?有一点大家还 ...

  5. Python基础教程(008)--第一个Python程序

    前言: 学会第一个Python程序 了解Python2和Python3的区别 内容 执行Python程序的三种方式 解释器--Python.Python3 交互式-- ipthon 集成开发环境--P ...

  6. python教程(二)·第一个python程序

    几乎所有的计算机语言教程,不仅仅是python,都以这样一个相似的示例程序开始讲解--Hello World! 代码如下,简简单单的一行.想必稍微了解英语的读者,都能猜到这段代码功能吧. print( ...

  7. JFinal教程:JFinal极速开发企业实战百集JFinal视频教程发布

    课程名称:JFinal极速开发企业实战 课程长度:100课时 课程作者:小木(909854136) 课程地址:http://edu.csdn.net/course/detail/1968 官网网址:h ...

  8. 创建一个jFinal项目

    最近在做微信开发,于是用到了jfinal. 做一下解释: JFinal 是基于 Java 语言的极速 WEB + ORM 开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩 ...

  9. Asp.Net MVC4.0 官方教程 入门指南之四--添加一个模型

    Asp.Net MVC4.0 官方教程 入门指南之四--添加一个模型 在这一节中,你将添加用于管理数据库中电影的类.这些类是ASP.NET MVC应用程序的模型部分. 你将使用.NET Framewo ...

随机推荐

  1. leetCode 24. Swap Nodes in Pairs (双数交换节点) 解题思路和方法

    Swap Nodes in Pairs  Given a linked list, swap every two adjacent nodes and return its head. For exa ...

  2. 人类科技的发展为什么会是加速度的(TRIZ方法再推荐)

    从人类的历史发展来看,近200年来的科技发展的成果超过了过去几千年中科技发展的成果,并且从短时间来看.这样的加速趋势也是很明显的,想想十年前和如今的对照,科技的发展确实是日新月异. 科技的发展固然有偶 ...

  3. Html.ActionLink(转载)

    @Html.ActionLink 代码: <h2>HtmlHelper</h2>@Html.ActionLink("默认","Index" ...

  4. Android学习之DragEvent

    关于DragEvent Google Android API中是这么说的 Represents an event that is sent out by the system at various t ...

  5. 关于RadUpload上传问题总结

    最近在开发上传控件,使用RadUpload上传大附件 发现了几个小问题,总结后分享给大家: 1.IE6浏览器下文件的路径显示的是物理路径,需要进行转换 2.IIS7.0 配置时要选择经典模式 3.we ...

  6. CheckBox控件实现选项的选中

    1:设置控件属性 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xml ...

  7. linux命令 收集

    https://jaywcjlove.github.io/linux-command/ 源码:https://github.com/jaywcjlove/linux-command Linux思维导图 ...

  8. plsql 的循环之 goto

    实例: /* 测试goto 的用法, */ procedure test_loop_go(pi_aab001 in number, po_fhz out varchar2, po_msg out va ...

  9. openstack、kvm CentOS升级内核

    openstack平台需要使用各种Linux发行版镜像,其制作方法主要有两种,要么是基于各大Linux发行版ISO光盘手动制作,要么是使用官方提供的制作好镜像进行修改 问题 FATAL: Module ...

  10. Linux解压缩总结

    看文件名的后缀名,不同的后缀的文件解压和压缩的命令都不一样总结如下: *.tar 用 tar –xvf 解压 *.gz 用 gzip -d或者gunzip 解压 *.tar.gz和*.tgz 用 ta ...