web框架之jfinal
介绍
web框架除了现最流行的spring mvc,还有其他如jfinal,jersery等。现在学习jfinal的基础。
jfinal有相关的开发者社区,其中最有名是一个叫“波总”的人。 官方文档在https://www.jfinal.com/doc/2-4。
jfinal的优点:开发极简,秒速启动,拥有很多与spring类似的特性,内嵌undertow,jetty,上手快,学习成本低。
jfinal的缺点:文档不够丰富,案例不够完善,感觉功能配套不是很齐全。
Hello World
jfinal的最重要的类是JFinalConfig,基本所有的相关的配置都是在这个类上进行。
最简单的使用:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57package io.github.black.jfinal.demo;
import com.jfinal.config.*;
import com.jfinal.json.JacksonFactory;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.template.Engine;
import io.github.black.jfinal.demo.controller.HelloController;
import io.github.black.jfinal.demo.entity._MappingKit;
import io.github.black.jfinal.demo.handler.ResourcesHandler;
public class DemoConfig extends JFinalConfig {
public static void main(String[] args) {
UndertowServer.start(DemoConfig.class,8091,true);
}
public void configConstant(Constants constants) {
constants.setDevMode(true);
}
public void configRoute(Routes routes) {
routes.add("/hello", HelloController.class);
}
public void configEngine(Engine engine) {
}
public void configPlugin(Plugins plugins) {
}
public void configInterceptor(Interceptors interceptors) {
}
public void configHandler(Handlers handlers) {
}
public void onStart() {
}
public void onStop() {
}
}
1 | public class HelloController extends Controller { |
然后打开浏览器http://localhost:8091/hello
很有意思的一点,可以很方便返回一个二维码:
首先添加maven配置:1
2
3
4
5<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
demo如下:1
2
3
4
5
6
7public void qrCode(){
// 二维码携带的数据
String data = "dengdb.github.io";
// 渲染二维码图片,长度与宽度为 200 像素
renderQrCode(data, 200, 200);
}
参数注入以及拦截器
jfinal使用@Inject进行字段进行注入,只能是由jfinal管理的对象才行,如controller,Interceptor等。对于非jfinal组件,可以使用Aop.get(); 至于Aop.inject()没找到该怎么用。1
2
3
4
5
6
7
8
9
10
11
12public class LoginService {
private LoginDao loginDao = Aop.get(LoginDao.class);
}
在jfinalConfig中开启配置
public void configConstant(Constants constants) {
constants.setDevMode(true);
// 开启对 jfinal web 项目组件 Controller、Interceptor、Validator 的注入
constants.setInjectDependency(true);
}
经过测试,在不同的地方使用Aop.get()获取到的是同一个对象。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class LoginServiceT {
private LoginDao loginDao = Aop.get(LoginDao.class);
public String loginT(){
System.out.println(loginDao);
return loginDao.save();
}
}
public class LoginService {
private LoginDao loginDao = Aop.get(LoginDao.class);
public String login(){
System.out.println(loginDao);
return loginDao.save();
}
}
查看控制台打印日志,两个loginDao为同一个对象。
关于jfinal的入参注入问题,官文有相关文档,大致有以下几种方式:
1.在Action中直接使用,jfinal自动转换。1
2
3
4
5
6public class HelloController extends Controller {
public void getJson(User user){
renderJson("name",user.getName());
}
}
我用post+json方式测试过,返回的是null,官文案例使用form表单方式,没测试过。
2.使用getPara()方式。 controller里内置了很多方法,如renderText(),renderJson,getPara()等,在controller中使用getpara()或者其重载方法,可以很方便的获取入参。
3.使用HttpKit。 jfinal内置了很多kit,如PropKit,Aop其实也算一个kit,DbKit。在controller中使用HttpKit可以获取入参:HttpKit.readData(getRequest());
JSON的支持
jfinal支持四种json,其中包括jacsonJson和fastJson。只需在jfinalConfig中配置即可。renderJson会按照配置的json进行转换。1
2
3
4
5
6
7
8
public void configConstant(Constants constants) {
constants.setDevMode(true);
//配置json
constants.setJsonFactory(new JacksonFactory());
// 开启对 jfinal web 项目组件 Controller、Interceptor、Validator 的注入
constants.setInjectDependency(true);
}
Model的使用
使用jfinal的generator生成model和配置。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53package io.github.black.jfinal.demo;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.druid.DruidPlugin;
import javax.sql.DataSource;
public class ModelGenerator {
private static DruidPlugin getDP(){
DruidPlugin dp = new DruidPlugin("jdbc:mysql://10.108.136.128/blackdb", "root", "123456");
return dp;
}
public static void main(String[] args) {
// base model 所使用的包名
String baseModelPkg = "io.github.black.jfinal.demo.entity.base";
// base model 文件保存路径
String baseModelDir = PathKit.getWebRootPath() + "/src/main/java/io/github/black/jfinal/demo/entity/base";
// model 所使用的包名
String modelPkg = "io.github.black.jfinal.demo.entity";
// model 文件保存路径
String modelDir = baseModelDir + "/..";
DruidPlugin dp = getDP();
dp.start();
DataSource ds = dp.getDataSource();
Generator gernerator = new Generator(ds, baseModelPkg, baseModelDir, modelPkg, modelDir);
// 在 getter、setter 方法上生成字段备注内容
gernerator.setGenerateRemarks(true);
// 设置是否生成链式 setter 方法
// gernerator.setGenerateChainSetter(false);
// 添加不需要生成的表名
// gernerator.addExcludedTable("adv");
//覆盖掉其中的 isSkipTable(String tableName) 方法,可以随心所欲控制想要的处理的 table
ModelMetaBuilder metaBuilder = new ModelMetaBuilder(ds);
gernerator.setMetaBuilder(metaBuilder);
// 设置是否在 Model 中生成 dao 对象
gernerator.setGenerateDaoInModel(true);
// 设置是否生成链式 setter 方法
gernerator.setGenerateChainSetter(true);
// 设置是否生成字典文件
gernerator.setGenerateDataDictionary(false);
// 设置需要被移除的表名前缀用于生成modelName。例如表名 "osc_user",移除前缀 "osc_"后生成的model名为 "User"而非 OscUser
// gernerator.setRemovedTableNamePrefixes("t_");
// 生成
gernerator.generate();
dp.stop();
}
}
小结:
生成器根据数据库配置,扫描相关的表,生成相应的model。这里最主要的是,获取DataSource,然后是配置model的包路径,baseModel一般在model的base下面;gernerator.addExcludedTable(“adv”)可以排除不需要的表,如果太多,也可以使用MetaBuilder,复写isSkipTable()方法,随心所欲的控制想要处理的table。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class ModelMetaBuilder extends MetaBuilder {
public ModelMetaBuilder(DataSource dataSource){
super(dataSource);
}
/**
* isSkipTable 方法 return true 时将过滤掉当前 table
* @param tableName
* @return
*/
protected boolean isSkipTable(String tableName) {
if("user".equalsIgnoreCase(tableName)|| "wesd_cert".equalsIgnoreCase(tableName)){
return false;
}
return true;
}
}
上诉代码执行后,会在model下生成一个_MappingKit类(或者其他名字),该类需要在jfinalConfig中使用1
2
3
4
5
6
7
8
9
public void configPlugin(Plugins plugins) {
DruidPlugin dp = new DruidPlugin("jdbc:mysql://10.108.136.128/blackdb", "root", "123456");
plugins.add(dp);
ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
_MappingKit.mapping(arp);
// arp.addMapping("user", User.class);
plugins.add(arp);
}
Kit的使用
PropKit.use()
HttpKit.readData(),HttpKit.post(),HttpKit.get()
DbKit.getConfig()
更多参考com.jfinal.kit包
总结
jfinal的开发和代码真的是极简,上手快。 但是实际应用的案例太少,还有很多的功能需要完善。
jfinal还有关于redis插件和其他模板渲染插件以及缓存插件,任务调度插件,以后再测试。