maven以及项目配置
打开 pom.xml 文件,在其中添加如下依赖
<dependencies>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal-undertow</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>4.3</version>
</dependency>
</dependencies>
JFinalConfig
- 基于JFinal的web项目需要创建一个继承自JFinalConfig类的子类,该类用于对整个web项目进行配置。
configConstant
```java
public void configConstant(Constants me) {
// 配置环境是否为开发模式
me.setDevMode(true);
}
```
configRoute
-
public void configRoute(Routes me) { // 如果要将控制器超类中的 public 方法映射为 action 配置成 true,一般不用配置 me.setMappingSuperClass(false); // 基本路径 me.setBaseViewPath("/view"); // 添加 Routes 级别的拦截器 me.addInterceptor(new FrontInterceptor()); // 第一个参数为url,第二个参数为控制器 me.add("/hello", HelloController.class); }
- 路由配置 API
public Routes add(String controllerKey, Class<? extends Controller> controllerClass, String viewPath) public Routes add(String controllerKey, Class<? extends Controller> controllerClass)
- 第一个参数 controllerKey 是指访问某个 Controller控制器 所需要的一个字符串,该字符串唯一对应一个 Controller控制器,controllerKey仅能定位到Controller。
- controllerKey ,规则如下
- JFinal默认使用减号“-”来分隔多个值
- 在Controller中可以通过getPara(int index)分别取出这些值。controllerKey、method、urlPara这三部分必须使用正斜杠“/”分隔。
- controllerKey自身也可以包含正斜杠“/”,如“/admin/article”,这样实质上实现了struts2的namespace命名空间功能。
- JFinal在以上路由规则之外还提供了ActionKey注解,可以打破原有规则,以下是代码示例:
public class UserController extends Controller { @ActionKey("/login") public void login() { render("login.html"); } } ```
- 假定 UserController 的 controllerKey值为“/user”,在使用了@ActionKey(“/login”)注解以后,actionKey由原来的“/user/login”变为了“/login”。该注解还可以让actionKey中使用减号或数字等字符,如“/user/123-456”。
- 路由拆分、模块化
public class FrontRoutes extends Routes { public void config() { // 设置基本视图路径 setBaseViewPath("/view/front"); // 添加路由 add("/", IndexController.class); add("/blog", BlogController.class); } } public class AdminRoutes extends Routes { public void config() { setBaseViewPath("/view/admin"); // 添加拦截器,该拦截器将拦截 AdminRoutes 中添加的所有 Controller addInterceptor(new AdminInterceptor()); add("/admin", AdminController.class); add("/admin/user", UserController.class); } } public class MyJFinalConfig extends JFinalConfig { public void configRoute(Routes me) { me.add(new FrontRoutes()); // 前端路由 me.add(new AdminRoutes()); // 后端路由 } public void configConstant(Constants me) {} public void configEngine(Engine me) {} public void configPlugin(Plugins me) {} public void configInterceptor(Interceptors me) {} public void configHandler(Handlers me) {} }
- 关于拦截器的话,后续教程应该会有,在aop中。
- controllerKey ,规则如下
- 第二个参数 controllerClass 是该 controllerKey 所对应到的 Controller控制器 。
- 第三个参数viewPath是指该Controller返回的视图的相对路径
configEngine
-
public void configEngine(Engine me) { me.addSharedFunction("/view/common/layout.html"); me.addSharedFunction("/view/common/paginate.html"); me.addSharedFunction("/view/admin/common/layout.html"); }
- 接受一个engine对象,添加模板
configPlugin
-
public void configPlugin(Plugins me) { DruidPlugin dp = new DruidPlugin(jdbcUrl, userName, password); me.add(dp); ActiveRecordPlugin arp = new ActiveRecordPlugin(dp); arp.addMapping("user", User.class); me.add(arp); }
- 此方法用来配置JFinal的Plugin,如下代码配置了Druid数据库连接池插件与ActiveRecord数据库访问插件。通过以下的配置,可以在应用中使用ActiveRecord非常方便地操作数据库。
configInterceptor
- 此方法用来配置JFinal的全局拦截器,全局拦截器将拦截所有 action 请求,除非使用@Clear在Controller中清除,如下代码配置了名为AuthInterceptor的拦截器。
-
public void configInterceptor(Interceptors me) { me.add(new AuthInterceptor()); }
configHandler
- 此方法用来配置JFinal的Handler,如下代码配置了名为ResourceHandler的处理器,Handler可以接管所有web请求,并对应用拥有完全的控制权,可以很方便地实现更高层的功能性扩展。
-
public void configHandler(Handlers me) { me.add(new ResourceHandler()); }
onStart()、onStop() 回调配置
// 系统启动完成后回调
public void onStart() {
}
// 系统关闭之前回调
public void onStop() {
}
Controller(上)
- Controller是JFinal核心类之一,该类作为MVC模式中的控制器。基于JFinal的Web应用的控制器需要继承该类。Controller是定义Action方法的地点,是组织Action的一种方式,一个Controller可以包含多个Action。Controller是线程安全的。
Action
- 在 Controller 之中定义的 public 方法称为Action。Action 是请求的最小单位。Action 方法必须在 Controller 中定义,且必须是 public 可见性。
- Action可以有返回值,返回值可在拦截器中通过invocation.getReturnValue() 获取到,以便进行render控制。
- 自 jfinal 3.6 开始,控制器超类中的所有方法默认不会被映射为 action。(控制器超类,指继承了Controller的中间控制器类,用它来创建其他控制器。)如果希望超类中的方法也被映射为 action 只需添加一行配置:
public void configRoute(Routes me) { me.setMappingSuperClass(true); }
Action 参数注入
- Action 参数注入是指为 action 方法传入参数,可以省去 getPara(…) 代码直接获得参数值
public class ProjectController extends Controller { public void index(Project project) { project.save(); render("index.html"); } }
get / getPara 系列方法
// 替代 getPara 的 get 用法
String title = get("title");
// 替代 getParaToInt 的 getInt 用法
Integer age = getInt("age");
// 替代 setAttr 的 set 用法,向request添加Attribute
set("article", article);
- jfinal 3.5 版本新增了 getRawData() 方法,可以很方便地从 http 请求 body 中获取 String 型的数据,通常这类数据是 json 或 XML 数据,例如:
String json = getRawData();
User user = FastJson.getJson().parse(json, User.class);
getBean / getModel 系列
实例:
// 定义Model,在此为Blog
public class Blog extends Model<Blog> {
}
// 在页面表单中采用modelName.attrName形式为作为表单域的name
<form action="/blog/save" method="post">
<input name="blog.title" type="text">
<input name="blog.content" type="text">
<input value="提交" type="submit">
</form>
public class BlogController extends Controller {
public void save() {
// 页面的modelName正好是Blog类名的首字母小写
Blog blog = getModel(Blog.class);
// 如果表单域的名称为 "otherName.title"可加上一个参数来获取
blog = getModel(Blog.class, "otherName");
}
}
render(String view)
- render(String view) 方法将对 view 所指向的模板进行渲染,view 参数最终指向的模板文件规则如下:
String template = baseViewPath + viewPath + view
- 三个参数取值,如下例子:
public void configRoute(Routes me) { // baseViewPath 为 "/_view",该 Routes 对象之下映射的所有 Controller 都将取这个值 me.setBaseViewPath("/_view"); // viewPath 为第三个参数 "/index" me.add("/", IndexController.class, "/index"); // 第三个参数省略时, viewPath 取第一个参数的值 : "/project" me.add("/project", ProjectController.class); } // 对于indexcontroller。 public class IndexController extends Controller { public void demo() { // 模板指向 : "/_view/index/abc.html" render("abc.html"); } }
- 当需要打破 baseViewPath 与 viewPath 这两个参数的限制时,view 参数以 “/” 打头即可
- render系列其他方法
- render系列方法将渲染不同类型的视图并返回给客户端。JFinal目前支持的视图类型有:JFinal Template、FreeMarker、JSP、Velocity、JSON、File、Text、Html、QrCode 二维码 等等。除了JFinal支持的视图型以外,还可以通过继承Render抽象类来无限扩展视图类型。
// 渲染名为test.html的视图,且视图类型为 JFinal Template renderTemplate("test.html"); // 生成二维码 renderQrCode("content"); // 渲染名为test.html的视图,且视图类型为FreeMarker renderFreeMarker("test.html"); // 渲染名为test.html的视图,且视图类型为Velocity renderVelocity("test.html"); // 将所有setAttr(..)设置的变量转换成 json 并渲染 renderJson(); // 以 "users" 为根,仅将 userList 中的数据转换成 json 并渲染 renderJson("users", userList); // 将user对象转换成 json 并渲染 renderJson(user); // 直接渲染 json 字符串 renderJson("{\"age\":18}" ); // 仅将setAttr(“user”, user)与setAttr(“blog”, blog)设置的属性转换成json并渲染 renderJson(new String[]{"user", "blog"}); // 渲染名为test.zip的文件,一般用于文件下载 renderFile("test.zip"); // 渲染纯文本内容 "Hello JFinal" renderText("Hello JFinal"); // 渲染 Html 内容 "Hello Html" renderHtml("Hello Html"); // 渲染名为 test.html 的文件,且状态为 404 renderError(404 , "test.html"); // 渲染名为 test.html 的文件,且状态为 500 renderError(500 , "test.html"); // 不渲染,即不向客户端返回数据 renderNull(); // 使用自定义的MyRender来渲染 render(new MyRender());
- 对于IE,使用ajax返回contentType为application/json数据时,使用
render(new JsonRender().forIE())或者render(new JsonRender(params).forIE())
以上内容来自官方文档JFinal开发教程,个人仅做简单整理。