资讯专栏INFORMATION COLUMN

快速上手JFinal

susheng / 1006人阅读

摘要:是国产的框架,由五大部分组成。本文通过一个例子上手,旨在熟悉中各组件的用法。指的是表名,指的是主键数据库连接池使用的是,还支持。默认访问方法,这点类似于如果之前有基础,上手会非常快。映射在上使用了校验拦截器,使用了权限拦截器。

JFinal是国产的MVC框架,由 Handler、Interceptor、Controller、Render、Plugin 五大部分组成。本文通过一个例子上手JFinal,旨在熟悉JFinal中各组件的用法。

目标

用户登录/注册

用户上传图片

登录权限验证

访问路径

用户登录:IP/user/login
用户注册:IP/user/register
用户上传图片:IP/user/image
登录后能访问: IP/user/show

依赖

druid-1.0.5.jar

cos-26Dec2008.jar

jfinal-2.0-bin.jar

log4j-1.2.16.jar

AppConfig

JFinal需要一个继承 JFinalConfig 的子类,我们这里取名叫AppConfig,这个类的名字是随便取的,我这里取AppConfig。

</>复制代码

  1. import com.jfinal.config.*;
  2. import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
  3. import com.jfinal.plugin.druid.DruidPlugin;
  4. import com.jfinal.render.ViewType;
  5. import controller.IndexController;
  6. import controller.UserController;
  7. import model.User;
  8. /**
  9. * Created by reeco_000 on 2015/7/22.
  10. */
  11. public class AppConfig extends JFinalConfig{
  12. @Override
  13. public void configConstant(Constants constants) {
  14. constants.setEncoding("UTF-8");
  15. constants.setDevMode(true);
  16. constants.setViewType(ViewType.JSP);
  17. }
  18. @Override
  19. public void configRoute(Routes routes) {
  20. routes.add("/", IndexController.class);
  21. routes.add("/user", UserController.class);
  22. }
  23. @Override
  24. public void configPlugin(Plugins plugins) {
  25. //这里启用Jfinal插件
  26. PropKit.use("jdbc.properties");
  27. final String URL =PropKit.get("jdbcUrl");
  28. final String USERNAME = PropKit.get("user");
  29. final String PASSWORD =PropKit.get("password");
  30. final Integer INITIALSIZE = PropKit.getInt("initialSize");
  31. final Integer MIDIDLE = PropKit.getInt("minIdle");
  32. final Integer MAXACTIVEE = PropKit.getInt("maxActivee");
  33. DruidPlugin druidPlugin = new DruidPlugin(URL,USERNAME,PASSWORD);
  34. druidPlugin.set(INITIALSIZE,MIDIDLE,MAXACTIVEE);
  35. druidPlugin.setFilters("stat,wall");
  36. plugins.add(druidPlugin);
  37. ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(druidPlugin);
  38. activeRecordPlugin.addMapping("user","userid", User.class);
  39. plugins.add(activeRecordPlugin);
  40. }
  41. @Override
  42. public void configInterceptor(Interceptors interceptors) {
  43. //这里用于配置全局的拦截器,对所有请求进行拦截
  44. }
  45. @Override
  46. public void configHandler(Handlers handlers) {
  47. }
  48. }
配置文件 Jdbc.properties

在根目录下新建一个Jdbc.properties,用来保存数据库连接信息。我们在AppConfig中需要加载它,使用了JFinal的工具类PropKit。

</>复制代码

  1. driverClass=com.mysql.jdbc.Driver
  2. jdbcUrl=jdbc:mysql://localhost:3306/school
  3. user=root
  4. password=root
  5. initialSize=1
  6. minIdle=1
  7. maxActivee=20
log4j.properties

这样就能使用log4j进行日志统计,在需要记录的地方获取logger对象即可

</>复制代码

  1. log4j.rootLogger=INFO, stdout, file
  2. log4j.appender.stdout.Target=System.out
  3. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  4. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  5. log4j.appender.stdout.layout.ConversionPattern=%n%-d{yyyy-MM-dd HH:mm:ss}%n[%p]-[Thread: %t]-[%C.%M()]: %m%n
  6. # Output to the File
  7. log4j.appender.file=org.apache.log4j.FileAppender
  8. log4j.appender.file.File=./web.log
  9. log4j.appender.file.layout=org.apache.log4j.PatternLayout
  10. log4j.appender.file.layout.ConversionPattern=%n%-d{yyyy-MM-dd HH:mm:ss}%n[%p]-[Thread: %t]-[%C.%M()]: %m%n
  11. # Druid
  12. log4j.logger.druid.sql=warn,stdout
  13. log4j.logger.druid.sql.DataSource=warn,stdout
  14. log4j.logger.druid.sql.Connection=warn,stdout
  15. log4j.logger.druid.sql.Statement=debug,stdout
  16. log4j.logger.druid.sql.ResultSet=warn,stdout
web.xml

然后在web.xml里配置JFinal的核心filter和我们写好的AppConfig

</>复制代码

  1. jfinal
  2. com.jfinal.core.JFinalFilter
  3. configClass
  4. AppConfig
  5. jfinal
  6. /*
Model

定义用户实体,代码非常简单

</>复制代码

  1. package model;
  2. import com.jfinal.plugin.activerecord.Model;
  3. /**
  4. * Created by reeco_000 on 2015/7/22.
  5. */
  6. public class User extends Model{
  7. }

继承Model就行了,无需 getter、setter 方法,无需Annotation,无需xml

这里数据库中user设计也很简单,就三个字段,userid,username,password,贴下sql:

</>复制代码

  1. DROP TABLE IF EXISTS `user`;
  2. CREATE TABLE `user` (
  3. `userid` int(11) NOT NULL AUTO_INCREMENT,
  4. `username` varchar(255) NOT NULL,
  5. `password` varchar(255) NOT NULL,
  6. PRIMARY KEY (`userid`)
  7. ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
Service

service层,封装业务逻辑。这里用到了ActiveRecord插件,需要在AppConfig中注册。

</>复制代码

  1. public void configPlugin(Plugins plugins) {
  2. //这里启用JFinal插件
  3. DruidPlugin druidPlugin = new DruidPlugin(URL,USERNAME,PASSWORD);
  4. druidPlugin.set(INITIALSIZE,MIDIDLE,MAXACTIVEE);
  5. druidPlugin.setFilters("stat,wall");
  6. plugins.add(druidPlugin);
  7. ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(druidPlugin);
  8. //添加Model类和数据库表的映射。user指的是表名,userid指的是主键
  9. activeRecordPlugin.addMapping("user","userid", User.class);
  10. plugins.add(activeRecordPlugin);
  11. }

数据库连接池使用的是Druid,JFinal还支持C3P0。
JFinal使用的是Db+Record 完成ORM。Db类提供了大量查询的方法,这种模式类似于ruby on rails。

</>复制代码

  1. package service;
  2. import com.jfinal.plugin.activerecord.Db;
  3. import com.jfinal.plugin.activerecord.Record;
  4. /**
  5. * Created by reeco_000 on 2015/7/22.
  6. */
  7. public class UserService {
  8. public boolean add(String username,String password){
  9. String SQL = "SELECT userid FROM user WHERE username =?";
  10. Integer result = Db.queryFirst(SQL, username);
  11. if(result==null){
  12. Record user = new Record().set("username", username).set("password", password);
  13. Db.save("user", user);
  14. return true;
  15. }
  16. return false;
  17. }
  18. public boolean login(String username,String password){
  19. String SQL = "SELECT userid FROM user WHERE username =? and password=?";
  20. Integer result = Db.queryFirst(SQL, username, password);
  21. if(result!=null)
  22. return true;
  23. else return false;
  24. }
  25. }
Interceptor

JFinal里的拦截器有三个作用域,全局,类和方法。利用JFinal的AOP,使用起来也非常方便。拦截器定义也非常简单,只需继承Interceptor接口重写intercept方法。全局的拦截器是在AppConfig里配置:

</>复制代码

  1. public void configInterceptor(Interceptors interceptors) {
  2. //这里用于配置全局的拦截器,对所有请求进行拦截
  3. // 添加控制层全局拦截器
  4. interceptors.addGlobalActionInterceptor(new GlobalActionInterceptor());
  5. // 添加业务层全局拦截器
  6. interceptors.addGlobalServiceInterceptor(new GlobalServiceInterceptor());
  7. }

类和方法使用@Before(Class.class)即能使用,具体可以看下面Controller的例子。在JFinal2还提供了Inject拦截器,不过我们的例子里没这需求,所以没用到,具体各位还是看官网文档吧。

AuthInterceptor

简易的权限拦截器,这里的作用是只有登录的才能执行。在session里设置了一个变量flag,当是true时就执行。

</>复制代码

  1. package interceptor;
  2. import com.jfinal.aop.Interceptor;
  3. import com.jfinal.aop.Invocation;
  4. import com.jfinal.core.Controller;
  5. /**
  6. * Created by reeco_000 on 2015/7/22.
  7. */
  8. public class AuthInterceptor implements Interceptor {
  9. @Override
  10. public void intercept(Invocation invocation) {
  11. Controller controller = invocation.getController();
  12. Boolean loginUser = controller.getSessionAttr("flag");
  13. if (loginUser ==true )
  14. invocation.invoke();
  15. else
  16. controller.redirect("/");
  17. }
  18. }
LoginValidator

Validator是JFinal提供的校验组件。其核心是Interceptor,所以用法和Interceptor类似,继承Validator类即可。

validate
提供了一系列的validateXXX方法

handleError
处理错误,常见的用法是

</>复制代码

  1. controller.keepPara();
  2. controller.render("register.html");

意思是返回原页面,保持传入的参数。


</>复制代码

  1. package validator;
  2. import com.jfinal.core.Controller;
  3. import com.jfinal.validate.Validator;
  4. /**
  5. * Created by reeco_000 on 2015/7/22.
  6. */
  7. public class LoginValidator extends Validator {
  8. @Override
  9. protected void validate(Controller c) {
  10. validateRequiredString("username","nameError","username is null");
  11. validateRequiredString("password","passError","username is null");
  12. }
  13. @Override
  14. protected void handleError(Controller c) {
  15. }
  16. }
Controller

JFinal的Controller需要继承Controller类,类的映射是在AppConfig中配置:

</>复制代码

  1. public void configRoute(Routes routes) {
  2. routes.add("/", IndexController.class);
  3. routes.add("/user", UserController.class);
  4. }

我们这里配置意思是/访问到IndexController这个类,/user 访问到UserController。/user/login 默认访问UserController.login()方法,这点类似于struct2,如果之前有基础,上手会非常快。

UserController

映射 /user,在login()上使用了校验拦截器LoginValidator,show()使用了权限拦截器AuthInterceptor。

</>复制代码

  1. package controller;
  2. import com.jfinal.aop.Before;
  3. import com.jfinal.core.Controller;
  4. import interceptor.AuthInterceptor;
  5. import service.UserService;
  6. import validator.LoginValidator;
  7. /**
  8. * Created by reeco_000 on 2015/7/22.
  9. */
  10. public class UserController extends Controller{
  11. private UserService userService = new UserService();
  12. public void index(){}
  13. @Before(LoginValidator.class)
  14. public void login(){
  15. String username = getPara("username");
  16. String password = getPara("password");
  17. boolean loginCheck = userService.login(username,password);
  18. if(loginCheck){
  19. renderJson("10000");
  20. getSession().setAttribute("flag",true);
  21. }
  22. else
  23. renderJson("10001");
  24. }
  25. public void register(){
  26. String username = getPara("username");
  27. String password = getPara("password");
  28. boolean result = userService.add(username,password);
  29. if(result)
  30. renderJson("10010");
  31. else
  32. renderJson("10011");
  33. }
  34. @Before(AuthInterceptor.class)
  35. public void show(){
  36. renderJsp("user.jsp");
  37. }
  38. public void image(){
  39. try{
  40. getFile(getPara("img"),"UTF-8");
  41. renderJson("20010");
  42. } catch (Exception e){
  43. renderJson("20012");
  44. }
  45. }
  46. }

getPara() 从请求中获取参数

getFile() 支持文件上传

renderJson() 返回JSON,JFinal提供了一系列的render方法,目前支持的视图类型有:
FreeMarker、JSP、Velocity、JSON、File、Text、Html 等等。

IndexController

</>复制代码

  1. package controller;
  2. import com.jfinal.core.Controller;
  3. /**
  4. * Created by reeco_000 on 2015/7/22.
  5. */
  6. public class IndexController extends Controller{
  7. public void index(){
  8. renderJsp("index.jsp");
  9. }
  10. }

index是Controller默认调用的方法

总结


最后整个工程的文件如上图所示,代码非常简单,我也就不上传献丑了。主要介绍了JFinal的Interceptor、Controller、Render、Plugin,Handler是对Controller和Interceptor的补充。ORM使用的是Db+ActiveRecord。JFinal还有很多组件没有提到,各位请到官网查看详细文档。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64426.html

相关文章

  • jFinal路由解析源码分析

    摘要:只是暴露接口,配置信息最终保存在的静态类中。整个项目只有一个,作为静态类可以保证它是唯一的,而它的静态成员也是整个项目中唯一的。至此的路由解析模块就分析完了。 jFinal的路由解析是在JFinalFilter中做的,这个Filter也需要在web.xml中配置。JFinalFilter实现了javax.servlet.Filter接口,从这里也可以看出jFinal是基于Servlet...

    CatalpaFlat 评论0 收藏0
  • 使用Jfinal编写的HTTP API应用脚手架项目

    摘要:目前已做好了一些基础的东西如配置,响应规范等和公共的模块,主要应用于接口快速开发。模块顾名思义表示令牌,用于标识当前用户,同时增加接口的安全性。在使用时,客户端必须在配置了拦截器的接口请求中携带名为的请求参数。 项目介绍 实际上这个项目更像一个脚手架,是我多次开发HTTP API应用的经验总结。其中包含了常用的模块(如账户相关,版本更新等),以及本人认为比较好的开发方式和规范。目前已做...

    baishancloud 评论0 收藏0
  • jfinal 日志log4j使用

    摘要:本文使用环境如何使用导入包将官网提供的包导入项目配置文件在项目配置文件中配置如下内容即可生效生成日志文件运行项目后将在根目录下生成的文件。 本文使用环境 win7 Idea 14.1.4 jfinal 2.0 1.jfinal如何使用log4j a.导入jar包 将官网提供的log4j.jar包导入项目 b.配置文件 在项目配置文件(project/src/log4j.prope...

    Little_XM 评论0 收藏0
  • jfinal 使用redis

    摘要:使用可以极度方便的使用,该插件不仅提供了丰富的,而且还同时支持多服务端。拥有超高的性能,丰富的数据结构,天然支持数据持久化,是目前应用非常广泛的数据库。 预设 Ubuntu 上 安装 redis 参见http://segmentfault.com/a/1190000004109484 概述 jfinal 2.0 中已集成RedisPlugin插件。 RedisPlugin 是支持 ...

    Harriet666 评论0 收藏0

发表评论

0条评论

susheng

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<