继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

JFinal极速开发框架使用笔记

二十三年一寒蝉
关注TA
已关注
手记 5
粉丝 29
获赞 72

记录第一次使用JFinal,从简单的框架搭建到增删改查,从自带的方法到正常框架习惯的使用方式。

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

JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率。

JFinal有如下主要特点:

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

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

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

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

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

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

Plugin体系结构,扩展性强

多视图支持,支持FreeMarker、JSP、Velocity

强大的Validator后端校验功能

功能齐全,拥有struts2的绝大部分功能

体积小仅632K,且无第三方依赖
例子:

本人用的maven,首先创建一个maven项目。

然后在pom.xml中引入jar包:

maven搜索jar包:http://mvnrepository.com/

官方demo的pom.xml:

这里没有引入json,我的这个demo最后的方法需要json

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.demo</groupId>
  <artifactId>jfinal_demo_for_maven</artifactId>
  <packaging>war</packaging>
  <version>3.2</version>
  <name>jfinal_demo_for_maven Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
  </properties>

      <!-- 使用阿里 maven 库 -->
    <repositories>
        <repository>
            <id>ali-maven</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>always</updatePolicy>
                <checksumPolicy>fail</checksumPolicy>
            </snapshots>
        </repository>
    </repositories>

    <!-- 添加快照版本库,updatePolicy: always、daily、interval、never -->
    <!-- repositories>
    <repository>
           <id>sonatype-nexus-snapshots</id>
           <name>Sonatype Nexus Snapshots</name>
           <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
           <releases>
               <enabled>false</enabled>
           </releases>
           <snapshots>
               <enabled>true</enabled>
               <updatePolicy>daily</updatePolicy>
           </snapshots>
       </repository>
      </repositories -->

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.jfinal</groupId>
        <artifactId>jetty-server</artifactId>
        <version>8.1.8</version>
        <!--
            此处的 scope 值为 compile 仅为支持 IDEA 下启动项目
            打 war 包时需要改成 provided,以免将一些无用的 jar 打进去
        -->
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>com.jfinal</groupId>
        <artifactId>jfinal</artifactId>
        <version>3.3</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.44</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.29</version>
    </dependency>
    <dependency>
        <groupId>com.jfinal</groupId>
        <artifactId>cos</artifactId>
        <version>2017.5</version>
    </dependency>

  </dependencies>

  <build>
    <finalName>jfinal_demo_for_maven</finalName>
        <plugins>
          <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>8.1.8.v20121106</version>
            <configuration>
                <stopKey>stop</stopKey>
                <stopPort>5599</stopPort>
                <webAppConfig>
                    <contextPath>/</contextPath>
                </webAppConfig>
                <scanIntervalSeconds>5</scanIntervalSeconds>
                <connectors>
                    <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
                        <port>80</port>
                        <maxIdleTime>60000</maxIdleTime>
                    </connector>
                </connectors>
            </configuration>
          </plugin>
      </plugins>
  </build>
</project>

然后是web.xml的配置:

注意:DemoConfig.java 文件所在的包以及自身文件名必须与 web.xml 中的 param-value 标签内的配置相一致(在本例中该配置为 demo.DemoConfig)。

<filter>
<filter-name>jfinal</filter-name>
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
<init-param>
<param-name>configClass</param-name>
<param-value>demo.DemoConfig</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jfinal</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

接下来创建java文件:

创建DemoConfig并继承JFinalConfig,DemoConfig是主文件,运行这个文件启动项目,就像运行普通java文件main一样,同时运行之后如果修改其他代码,并不需要重启,框架会自动修改,直接刷新就可以看到修改后的内容。

这是初始的简单的demo:

package demo;
import com.jfinal.config.*;
public class DemoConfig extends JFinalConfig {
public void configConstant(Constants me) {
me.setDevMode(true);
}
public void configRoute(Routes me) {
me.add("/hello", HelloController.class);
}
public void configEngine(Engine me) {}
public void configPlugin(Plugins me) {}
public void configInterceptor(Interceptors me) {}
public void configHandler(Handlers me) {}
}

然后配置controller:

package demo;
import com.jfinal.core.Controller;
public class HelloController extends Controller {
public void index() {
renderText("Hello JFinal World.");
}
}

然后直接打开浏览器输入http://localhost/hello 就可以看到页面输出了 Hello JFinal World 。

这是最基本的使用的例子,下面是我的程序:


``package demo;

import com.jfinal.config.*;

import com.jfinal.core.JFinal;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.c3p0.C3p0Plugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.template.Engine;

import controller.StudentController;
import demo.model.Classes;
import demo.model.Student;

public class DemoConfig extends JFinalConfig {

    public static void main(String[] args) {
        JFinal.start("src/main/webapp", 80, "/", 5);
    }

    public void configConstant(Constants me) {
        me.setDevMode(true);
        //此方法用来配置 JFinal 常量值,如开发模式常量 devMode 的配置,如下代码配置了 JFinal
        //运行在开发模式:在开发模式下,JFinal 会对每次请求输出报告,如输出本次请求的 URL、Controller、Method
        //以及请求所携带的参数。
    }

    public void configRoute(Routes me) {
        me.add("/", HelloController.class);
        me.add("/test/mytest", HelloController.class,"test");
        me.add("/student", StudentController.class);
        //me.add("/classes", ClassesController.class);
    }

    public void configEngine(Engine me) {

    }

    public void configPlugin(Plugins me) {

//        C3p0Plugin  cp  =  new  C3p0Plugin("jdbc:mysql://localhost/db_name", 
//            "userName", "password");
//            me.add(cp);

        loadPropertyFile("a_little_config.txt");
        DruidPlugin dp = new DruidPlugin(getProperty("jdbcUrl"),
        getProperty("user"), getProperty("password"));
        me.add(dp);
        ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
        me.add(arp);
        arp.addMapping("student", "studentid", Student.class);
        arp.addMapping("classes", "classesid", Classes.class);

//        此方法用来配置JFinal的Plugin,如下代码配置了Druid数据库连接池插件与ActiveRecord
//        数据库访问插件。通过以下的配置,可以在应用中使用 ActiveRecord 非常方便地操作数据库。
    }

    public void configInterceptor(Interceptors me) {
        //me.add(new AuthInterceptor());

//        此方法用来配置 JFinal 的全局拦截器,全局拦截器将拦截所有 action 请求,除非使用
//        @Clear 在 Controller 中清除,如下代码配置了名为 AuthInterceptor 的拦截器。
    }

    public void configHandler(Handlers me) {
    }

}

这里面各个方法的简单说明都写在注释里了。

然后是controller:

这里虽然声明了service,但是并没有使用的,都是直接在controller方法里使用dao

package controller;

import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;

import StudentInterceptor.StudentInterceptor;
import StudentValidator.StudentValidator;
import StudentValidator.StudentValidator2;
import demo.model.Student;
import service.StudentService;

public class StudentController extends Controller {

    /**
     * 获取studentid那里有多种方法,这个要和前台传参写法一致,Controller 提供了 getPara 系列方法,官网api里很详细

jfinal用的是原生态sql语句,简单,方便,setAttr("studentList", list);把结果集放到request范围里,

jfinal也有直接获取表单里分装成对象的方法 getModel(Student.class);就是,和struts2一样,表单name对应上就可以了,非常方便

添加那里对于oracle用序列维护studentid      student.set("studentid", "mysequence.nextval").save(); jfinal有多种返回方式,也可以返回json数据,render 系列方法,官网api里很详细
     */

    static StudentService service = new StudentService();

    @Before(StudentInterceptor.class)
    public void index() {
        List<Student> list = Student.dao.find("select * from student");
        setAttr("studentList", list);
        //注意下面路径的的前面如果带/则从根目录下开始找,也就是说 下代码 = render("/student/index.html");
        render("index.html");
    }

    public void add() {
        render("add.html");
    }

    public void test() {
        List<Student> list = Student.dao.find("select * from student");
        setAttr("studentList", list);
        setAttr("student", list.get(0));
        render("test.jsp");
    }

    public void getlist() {
        List<Student> list = Student.dao.find("select * from student");
        JSONObject jo = new JSONObject();
        jo.put("code", 0);
        jo.put("msg", true);
        jo.put("count",list.size());
        jo.put("data", list);
        renderJson(jo);
    }

    public void layui() {
        List<Student> list = Student.dao.find("select * from student");
        setAttr("studentList", list);
        render("index3.html");
    }

    public void delete() {
        // 获取表单域名为studentid的值
        Student.dao.deleteById(getPara("studentid"));
        forwardAction("/student");
    }

    public void delete1() {
        // 获取url请求中第一个值
        Student.dao.deleteById(getParaToInt());
        forwardAction("/student");
    }

    public void update() {
        Student student = getModel(Student.class);
        student.update();
        forwardAction("/student");
    }

    public void get() {
        Student student = Student.dao.findById(getPara("studentid"));
        setAttr("student", student);
        render("index2.html");
    }

    public void get1() {
        Student student = Student.dao.findById(getParaToInt());
        setAttr("student", student);
        render("index2.html");
    }

    @Before(StudentValidator.class)
    public void save() {
        /**
         * getModel用来接收页面表单域传递过来的model对象,表单域名称以”modelName.attrName”
http://www.jfinal.com
方式命名,getModel 使用的 attrName 必须与数据表字段名完全一样。
getBean 方法用于支持传统 Java Bean,包括支持使用 jfnal 生成器生成了 getter、setter 方法
的 Model,页面表单传参时使用与 setter 方法相一致的 attrName,而非数据表字段名。
getModel与getBean区别在于前者使用数表字段名而后者使用与setter方法一致的属性名进
行数据注入。建议优先使用 getBean 方法。
         */
        //getBean(Student.class).save();
        getModel(Student.class).save();
        redirect("/student");
    }

    @Before(StudentValidator2.class)
    public void savebean() {
        getBean(Student.class).save();
        redirect("/student");
    }

}

同样的简单的说明也写在注释里了。

方法基本上都在这里了,下面是其他的一些配置:

这是实体类:


```package StudentValidator;

import com.jfinal.core.Controller;
import com.jfinal.validate.Validator;

public class StudentValidator extends Validator {

    //在校验失败时才会调用
    @Override
    protected void handleError(Controller controller) {
        controller.keepPara("student.studentname");//将提交的值再传回页面以便保持原先输入的值
        controller.render("/add.html");
    }

    @Override
    protected void validate(Controller controller) {
        //验证表单域name,返回信息key,返回信息value
        validateRequiredString("student.studentname", "studentnameMsg",
                "请输入学生名称!");
    }

}
package StudentValidator;

import com.jfinal.core.Controller;
import com.jfinal.validate.Validator;

public class StudentValidator2 extends Validator {

    //在校验失败时才会调用
    @Override
    protected void handleError(Controller controller) {
        controller.keepPara("studentname");//将提交的值再传回页面以便保持原先输入的值
        controller.render("/add.html");
    }

    @Override
    protected void validate(Controller controller) {
        //验证表单域name,返回信息key,返回信息value
        validateRequiredString("studentname", "studentnameMsg",
                "请输入学生名称!");
    }
}

StudentInterceptor:

package StudentInterceptor;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;

public class StudentInterceptor implements Interceptor {

    public void intercept(Invocation ai) {
        System.out.println("Before action invoking");
        ai.invoke();
        System.out.println("After action invoking");
    }
}

然后是前台的显示页面:
因为上传篇幅限制,在下一篇手记:

打开App,阅读手记
11人推荐
发表评论
随时随地看视频慕课网APP