先从Controller入手,用户登录,经过路由转发,到达Controller类,在Action中进行对应的处理。
1.登录:
地址:http://localhost:8080/Jdemo/index.jsp
跳转:http://localhost:8080/Jdemo/users/loginUsers
Action类的代码:
@Before(ControllerInterceptor.class) public class UsersController extends Controller { private IUsersService us = new UsersServiceImpl(); /** * 用户登录Action */ @Before({ LoginValidator.class, ActionInterceptor.class }) public void loginUsers() { String uName = getPara("USERS.UNAME"); String uPswd = getPara("USERS.UPSWD"); Users u = us.getUsers(uName, uPswd); System.out.println(u); if (null != u) { setSessionAttr("CURRENT_USER", u); renderJsp("/users/home.jsp"); } else { setAttr("loginUsersMsg", "用户名或密码错误!"); renderJsp("/index.jsp"); } } }
使用Annotation无侵入式的在类上别添加了Controller级别的拦截器,在Action上添加了Action级别的拦截器和登录校验。
在配置类中添加Global级别的拦截器
@Override public void configInterceptor(Interceptors me) { me.add(new GlobalInterceptor()); }
下面是登录动作完成后,控制台显示信息,可以反映一次请求应答过程。
分析说明:
第一步:全局拦截器;
第二步:进入Controller级别拦截器;
第三步:为loginUsers方法设置了校验类,进入校验方法(校验通过进入第四步)
第四步:进入Action级别拦截器;
第五步:通过Action将请求信息传信息给Service和Model进行数据处理,并返回到视图;
第六步:各级别拦截器以栈的顺序退出。
2.查看所有用户:
地址:http://localhost:8080/Jdemo/users/showUsersList
转到:http://localhost:8080/Jdemo/users/home.jsp页面
Action类代码:
/** * 获取所有用户的信息的Action */ public void showUsersList() { @SuppressWarnings("unchecked") List<Users> listUsers = us.getUsersAll(); setAttr("LIST_USERS", listUsers); renderJsp("/users/home.jsp"); }
执行流程结束,控制台信息:
从控制台显示信息可以看到没有了Action级别的拦截器,同是可以看到showUsersList()方法上也没有添加注解信息(Action级别的拦截器)。
3.上传文件:
Jsmart/JFinal提供了非常方便的可上传10M的大小的文件。
上传文件的方法很简单,直接调用Controller的方法,getFile(...);
参见例子:
/** * 上传用户资料的Action */ public void uploadImage() { String uId = getPara("uId"); String realPath = getPara("realPath"); String uploadPath = ServiceUtils.newSaveDir(realPath); //******************************************* //***********获取表单中的File立即上传******** //******************************************* UploadFile ufile = getFile("uImage", uploadPath); if (null != ufile) { ServiceUtils.renameFile(ufile, uId); setSessionAttr("UPLOAD_MSG", "上传成功!"); } else { setSessionAttr("UPLOAD_MSG", "上传失败!"); } redirect("/users/showUsersList"); }
JFinal的作者给出的修改上传文件名的方式和我做的不谋而合,这也是提供一种为上传文件添加时间戳的方式。
上面代码中的ServiceUtils.renameFile(UploadFile uploadFile, <Type> newName)给予具体实现。
public static void renameFile(UploadFile uf, String newName) { File uf.getFile(); String srcName = src.getName(); String dstName = src.getParent() + File.separator + newName + srcName.substring(srcName.indexOf('.')); File dst = new File(dstName); /** * 重命名的文件存在则删除! */ if (dst.exists()) { dst.delete(); } src.renameTo(dst); }
关于文件下载,JFinal/Jsmart框架提供了一个很好用的方法renderFile(File f);该法直接为页面产生一个指定的下载文件,非常简单方便。
JFinal/Jsmart框架很灵活,很注重解决实际问题,撇开了很多很少用到的功能,并提供了插件机制为扩展提供的基础。
框架工作流程如上面两个例子1,2,文件下载,上传如例子3。
关于数据访问很有ibatis的味道,通过配置sql,Model和数据库表映射来完成。
表映射
package com.broncho.jsmart.model.users; import com.jsmart.ext.plugin.tablebind.TableBind; import com.jsmart.plugin.activerecord.Model; /** * Users表的数据模型 * * @author Broncho * @time 2013年7月17日 09:17:18 */ @TableBind(tableName = "USERS", pkName = "UID") public class Users extends Model<Users> { /** * */ private static final long serialVersionUID = 5631774099405889205L; /** * Users数据模型的共享对象 */ public static final Users dao = new Users(); }
数据库访问
配置SQL文件
<?xml version="1.0" encoding="UTF-8"?> <sqlGroup name="USERS"> <sql id="queryCurrentUsers"> SELECT * FROM USERS WHERE UNAME=? AND UPSWD=? </sql> </sqlGroup>
查询实例:
@Override public Users getUsers(String uName, String uPswd) { List<Users> ulist = null; ulist=Users.dao.find("USERS.queryCurrentUsers", new Object[]{uName,uPswd}); Users u = null; if (null != ulist && ulist.size() != 0) { u = ulist.get(0); } return u; }
注:SQL配置文件的命名,xxx-sql.xml
SQL配置文件使用了Group-Id的方式来管理SQL语句,这样就可以用GroupName.Id的方式使用配置好的SQL语句。
JFinal正真的做到了所描述的那些特性,而每一种特性都可一从已有的框架中看到,学习起来容易,比如:Action和Struts2的Action同理,Model层的数据库访问和ibatis框架同理,还有体现了约定优于配置,做到了可扩展,可插拔的,轻量级,无依赖的优势。JFinal更像是化繁为简,为己所有的一款框架,更像是开发者为了逃离繁琐,减轻学习负担而开发的框架。
本文出自 “野马红尘” 博客,谢绝转载!