1.初识JFinal框架
JFinal框架学习日记
[TOC]
JFinal框架入门项目搭建
1.Maven工程搭建与配置
groupId和artifactId被统称为“坐标”,是为了保证项目唯一性而提出的,若要将项目加载到maven本地仓库中,则可根据这两个数据进行定位 groupId一般分为多个段,第一段为域,第二段为公司名称。域又分为org、com、cn等等许多,其中org为非营利组织,com为商业组织。
举个apache公司的tomcat项目例子:这个项目的groupId是org.apache,它的域是org(因为tomcat是非营利项目),公司名称是apache,artigactId是tomcat。 自定义:groupId可设置为“cn.xxx”,cn表示域为中国,xxx可以是指定的任意内容(例如名字缩写),artifactId则可设置为对应的项目名称(例如demo),依此结构,项目中设置的包的结构最好按照这种规范,以此开头随后根据不同的包类型进行定义。完整包结构可以为“cn.ljl.demo.dao”等
完成创建之后,可见工程报错,因此需要对项目进行配置,配置完成Update Maven Project完成更新即可(此处参考此前整理的Maven工程创建配置)
【1】pom.xml文件修改
在pom.xml删除不必要的依赖,并加入以下内容:用以控制jdk版本
<build>
<finalName>项目名称</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
【2】web.xml文件修改
需要更改web.xml头文件的web版本
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>Archetype Created Web Application</display-name>
</web-app>
【3】通过Navigator视图完成数据的修改
视图可以通过window –>show view 显示,选择Navigator,更改如下内容:修改jdk版本、web版本
工程上右键builder path:修改如下jar包,并将工程添加指定的服务器(Tomcat配置,此处示例是在jfinal-undertow环境下开发,暂时无需添加tomcat服务环境)
完成配置之后检查配置信息是否成功,右键工程选择properties->Project Facets,查看对应的jdk版本和web版本是否一致,如果不一致则要进行查阅、修改
【4】Maven相关依赖引入
JFinal相关依赖引入(WebSocket相关依赖引入)
<!-- JFinal框架相关JAR引入 -->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal-undertow</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>4.7</version>
</dependency>
<!-- WebSocket依赖引入 -->
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
<version>2.0.25.Final</version>
</dependency>
2.Server环境运行测试
每种环境配置需参考步骤,不要混乱配置,可能导致项目启动报错(还需考虑eclipse、idea中不同的启动问题)
【1】jfinal-undertow下开发
在项目 src/main/java 目录下创建demo包,并在 demo 包下创建 HelloController文件
在 demo 包下创建 DemoConfig 文件
搭建完成,右键选中DemoConfig文件,选择Run AsàJava Application等待项目启动,随后在浏览器中输入http://localhost/hello查看运行效果
jfinal-undertow 不支持 JSP,建议使用 jfinal 默认的模板引擎 enjoy。如果一定要使用 JSP,可以使用 jetty-server https://www.jfinal.com/doc/1-6 作为开发环境
【2】jetty-server下开发
Jetty-server下开发步骤基本可参考jfinal-undertow下开发的步骤详情,此处需要进行变动的如下说明
a.pom.xml依赖引入
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>4.7</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jetty-server</artifactId>
<version>2019.3</version>
<scope>provided</scope>
</dependency>
<!-- 下面的依赖仅在使用 JSP 时才需要 -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jsp</artifactId>
<version>9.2.26.v20180806</version>
<scope>provided</scope>
</dependency>
(亦可通过引入Maven内置的Jetty配置进行操作)
依赖引入说明:jetty-server 依赖的 scope 为 provided,仅用于开发阶段,部署时不需要,打包时也会自动跳过。如果是使用 IDEA 开发,scope 仍然得设置成为 compile,否则提示缺少 jar 包,在打包的时候记得要改回 provided,避免打进一些不需要的 jar 包
b.java文件调整
基本java文件内容参考上述jfinal-undertow下开发,但在DemoCinfig文件中的main方法中
JFinal.start("src/main/webapp",80,"/",5);
可能存在问题:
在运行的时候始终报404错误,但程序本身是没有问题的,若直接访问主路径进行测试http://localhost:8080,则出现如下问题
通过window->preferences,修改相关jre环境配置,再次启动程序进行测试
启动后如若出现如下错误,则可能是JDK版本与引入的jetty-server不兼容,需要调整jetty-server版本以匹配相应版本的jdk(实际参考对应版本说明)
c.maven内置jetty配置
或者是直接通过使用maven内置的jetty-server进行操作
在pom.xml文件中添加jetty-server插件,随后通过maven指令启动jetty服务器(jetty:run)
启动完成访问链接:http://localhost:8088/JFinal_Demo/(访问index.jsp文件)
d.jetty-server+jfinal项目构建说明
<1>创建标准的maven项目(与jfinal undertow类似)
<2>添加jfinal与jetty server相关的依赖
jetty-server依赖的scope为provided,仅用于开发阶段,部署时不需要,打包时也会自动跳过
但需要特别注意的是:如果使用IDEA开发,scope仍然得设置成compile,否则提示缺少jar包;在打包的时候可以调整为provided,避免打入一些不必要的jar
JFinal4.5版本与jetty-2018.11,pom中jetty的scope需要调整为compile否则提示缺失jar
【4】tomcat下部署
a.web.xml文件配置
其中的 para-value 配置取决于你项目的具体 XxxConfig 的包名与类名,注意修改(调整为自身项目配置类所在完成路径配置),其它配置可原封不动进行复制
b.pom.xml文件配置
项目<packaging>
属性调整为“war”
删掉 jfinal-undertow和 jetty-server相关依赖,否则部署到 tomcat 中会产生冲突
c.访问测试:http://localhost:8080/hello
此处配置maven内置的tomcat插件,通过mvn指令(tomcat7:run)启动tomcat,JFinal_Demo项目正常启动;随后访问相应链接测试项目是否正常运行
3.JBolt插件下开发
JBolt详细使用图文教程:http://www.jfinal.com/share/1052
JBolt官网:http://www.jbolt.cn/
【1】下载安装配置JBolt
下载最新的JBolt的zip包,随后将其解压到eclipse安装目录下的plugins目录
重启eclipse,可看到上方选项卡有JBolt选项,选中点击JBolt Home进入主页,随后点击“update libs”更新资源库(或者直接选中点击),更新完成可看到如下内容
【2】简单项目配置测试
待数据更新完成,点击创建Web Project
服务器访问配置:
数据库连接配置:
存在问题说明:Web Project创建完成之后在相应的工程目录下的lib文件夹中没有找到指定的第三方类库,使用maven引入的工程则由pom.xml配置文件统一管理jar(版本兼容问题,替换成较低版本的JBolt插件即可)
【3】Model生成
右键选择指定工程,选中JBolt->Generator->JFinal Model Generator
随后完善数据库配置信息
选择要生成的model,指定其生成的包结构,点击finish完成操作,即可在指定的目录下查看相应数据
配置完成可看到对应目录生成相应的model实体类
【4】项目运行
项目右键带着专用的Jetty Run,Maven版本也有专门定制的菜单启动;(配置失败,可能是由于jbolt版本过高导致,更换版本后再次尝试配置)
此处对应版本说明如下,选择替换成1.4.1版本的JBolt
右键项目选择“run as->jetty run”,启动成功可在console窗口查看相关信息
【5】EnjoyEditor(专属编辑器体验)
4.项目扩展
【1】配置文件动态切换
a.配置说明
maven profile动态选择配置文件:https://www.cnblogs.com/eyesfree/p/11491495.html
<1>在resources下根据开发需求配置多套配置文件(dev、product、test)
<2>在pom.xml文件中配置<profiles>环境管理与<build>打包参数
b.配置步骤
<!-- 配置环境管理 -->
<profiles>
<profile>
<!-- 本地开发环境 -->
<id>dev</id>
<properties>
<!-- profiles.active节点是自定义的,后续根据这个节点名称切换相应的配置信息 -->
<profiles.active>dev</profiles.active>
</properties>
<activation>
<!-- 设置默认激活指定profile配置 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!-- linux环境 -->
<id>linux</id>
<properties>
<profiles.active>linux</profiles.active>
</properties>
</profile>
<profile>
<!-- 生产环境 -->
<id>product</id>
<properties>
<profiles.active>product</profiles.active>
</properties>
</profile>
<profile>
<!-- 测试环境 -->
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
</profiles>
<build>
<!-- 配置打包参数 -->
<finalName>report</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>config/dev/*</exclude>
<exclude>config/linux/*</exclude>
<exclude>config/product/*</exclude>
<exclude>config/test/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources/config/${profiles.active}</directory>
</resource>
</resources>
<!--
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<warSourceExcludes>
config/dev/**,config/linux/**,config/product/**,config/test/**,
</warSourceExcludes>
<webResources>
<resource>
<directory>src/main/resources/config/${profiles.active}</directory>
<targetPath>config</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
-->
</build>
配置完成更新项目,可在maven管理窗口切换相应的配置
项目打包说明
可以通过maven指令:mvn package -P xxx(配置属性名称)
根据选中配置文件打包:可借助选项卡窗口,先选中某一个配置参数,依次执行clean、compile、package(要注意清理和重新编译,否则直接打包的配置可能会‘脏数据’,原执行配置文件未清理干净)
c.常见问题
配置文件不生效,加载失败
调整成使用ProKit.use方式:PropKit.use("config.txt");项目正常启动
【2】日志配置
a.配置说明
以Jfinal4.5+jetty-server2018.11为参考
<1>在pom.xml中引入日志处理相关jar
<2>在resources下配置log4j.properties文件
<3>在Jfinal主配置文件中配置日志打印开关(开发模式-是否打印运行日志;SQL打印开关)
b.配置步骤
在pom.xml中引入日志处理相关jar
<properties>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.6.4</slf4j.version>
</properties>
<!-- 日志处理 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
在resources下配置log4j.properties文件
log4j.rootLogger=INFO,stdout,file
#log4j.rootLogger=debug,stdout,D,E
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%n%-d{yyyy-MM-dd HH:mm:ss}%n[%p]-[Thread: %t]-[%C.%M()]: %m%n
# Output to the File
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=./report_logs/report_demo.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%n%-d{yyyy-MM-dd HH:mm:ss}%n[%p]-[Thread: %t]-[%C.%M()]: %m%n
在Jfinal主配置文件中配置日志打印开关(开发模式-是否打印运行日志;SQL打印开关)
# SystemConst参数配置
// 开发模式配置参数
public static final String DEV_MODE = "devMode";
// 日志打印配置参数
public static final String SHOW_SQL = "showSql";
# Jfinal主配置文件
public class MainConfig extends JFinalConfig {
@Override
public void configConstant(Constants constants) {
// 配置文件引入(通过maven的profile切换不同的配置环境)
PropKit.use("config.txt");
// loadPropertyFile("config.txt");
// 开发模式:打印运行日志
constants.setDevMode(PropKit.getBoolean(SystemConst.DEV_MODE));
// ...... 其他配置 ......
}
@Override
public void configPlugin(Plugins plugins) {
// 数据库配置(oracle)
DruidPlugin druidPlugin = new DruidPlugin(PropKit.get("url"), PropKit.get("username"),
PropKit.get("password"), PropKit.get("driverClass"));
plugins.add(druidPlugin);
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
// 载入oracle版本的SQL语句模板
arp.addSqlTemplate("/sqlTemplate/hgfx_jkyj.sql");
// oracle配置-设置数据库方言
arp.setDialect(new OracleDialect());
// oracle配置-忽略大小写
arp.setContainerFactory(new CaseInsensitiveContainerFactory());
// sql语句打印配置(根据参数确认:true-打印开启;false-打印关闭)
arp.setShowSql(PropKit.getBoolean(SystemConst.SHOW_SQL));
// 载入数据库表-实体映射配置文件
_MappingKit.mapping(arp);
// 加载插件配置
plugins.add(arp);
}
}
c.常见问题
【3】缓存配置
a.配置说明
以Jfinal4.5+jetty-server2018.11为参考
<1>在pom.xml中引入ehcahe缓存相关jar
<2>在resources文件夹下引入缓存配置文件ehcache.xml
<3>Jfinal主配置文件中配置缓存插件
b.配置步骤
在pom.xml中引入ehcahe缓存相关jar
<properties>
<ehcache-core.version>2.6.6</ehcache-core.version>
</properties>
<!-- 引入ehcahe缓存相关 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache-core.version}</version>
</dependency>
在resources文件夹下引入缓存配置文件ehcache.xml(可创建config文件夹统一管理相关配置文件)
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true">
<!--默认缓存-->
<defaultCache
maxEntriesLocalHeap="1000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="7200"
timeToLiveSeconds="60">
</defaultCache>
<!-- 用户登录信息缓存 -->
<cache name="loginCache"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="true"
diskPersistent="true"
/>
</ehcache>
Jfinal主配置文件中配置缓存插件
# Jfinal主配置文件
public class MainConfig extends JFinalConfig {
@Override
public void configPlugin(Plugins plugins) {
// ----- 其他数据库相关配置 ------
/**
* 配置ehCache缓存(默认resources文件夹下的指定名称的配置文件,
* 如果需额外指定配置文件则需强调ehcache.xml所在路径url)
**/
// URL url = new URL();
plugins.add(new EhCachePlugin());
}
}
c.常见问题
idea配置echache.xml报错Cannot resolve file 'ehcache.xsd
1.打开settings->languages&frameworks->schemas and dtds ,添加地址 http://ehcache.org/ehcache.xsd
2.修改ehcache.xml :
原eclipse:xsi:noNamespaceSchemaLocation="ehcache.xsd"
idea:xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true">
【4】拦截器配置
a.配置说明
以Jfinal4.5+jetty-server2018.11为参考
<1>拦截器定义:例如登录拦截校验、用户访问权限拦截、jfinal全局异常拦截器定义
<2>在Jfinal主配置文件中加载拦截器
参考链接:https://www.cnblogs.com/chen-lhx/p/4855997.html
日志结合自定义异常:https://blog.csdn.net/u010924845/article/details/50083257
b.配置步骤
自定义拦截器配置:登录拦截器、权限校验器、异常拦截器
- 登录拦截器
public class LoginInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);
/**
* 拦截控制器方法请求,判断缓存中是否有对应sessionId的用户登录,若不为null则放行
* */
@Override
public void intercept(Invocation inv) {
logger.info("----------登录拦截----------");
Controller controller = inv.getController();
String sessionId = controller.getSession().getId();
Record loginUser = CacheKit.get(SystemConst.LOGIN_CACHE, sessionId);
if(loginUser != null) {
inv.invoke();
}else {
// controller.redirect(SystemConst.LOGIN_URL);
// 用户未登录不允许放行,跳转到登录页面
controller.renderJson(AjaxResultUtil.error(ResultEnum.NO_LOGIN));
// controller.render(SystemConst.LOGIN_URL);
}
logger.info("----------登录拦截处理完成----------");
}
}
- 权限校验器
/**
* 管理员拦截器(针对超级管理员和系统管理员共有的权限)
**/
public class AdminInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(AdminInterceptor.class);
/**
* 拦截控制器方法请求用于超级管理员权限校验
* */
@Override
public void intercept(Invocation inv) {
logger.info("----------START-管理员权限拦截----------");
Controller controller = inv.getController();
String sessionId = controller.getSession().getId();
Record loginUser = CacheKit.get(SystemConst.LOGIN_CACHE, sessionId);
// 校验用户关联角色KEY,如果KEY为指定管理员标识则放行
if(loginUser != null) {
String roleKey = loginUser.getStr("roleKey");
// 校验用户关联角色,如果为管理员角色则放行(针对超级)
if(SystemConst.ROLE_SUPER_ADMIN.equals(roleKey)
||SystemConst.ROLE_SYS_ADMIN.equals(roleKey)){
inv.invoke();
}else{
controller.renderJson(AjaxResultUtil.error(ResultEnum.NO_AUTH_ERROR));
}
}else {
// controller.redirect(SystemConst.LOGIN_URL);
// 用户未登录不允许放行
controller.renderJson(AjaxResultUtil.error(ResultEnum.NO_LOGIN));
}
logger.info("----------END-管理员权限拦截----------");
}
}
- 异常拦截器
public class GlobalExceptionInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionInterceptor.class);
@Override
public void intercept(Invocation invocation) {
// 获取Controller对象
Controller controller = invocation.getController();
// 如果捕获到异常则相应跳转指定错误提示
// try {
// invocation.invoke();
// } catch (Exception e) {
// if (e instanceof ReportException) {
// // 处理 xxxException;
// controller.renderJson(AjaxResultUtil.error(e.getMessage()));
// }
// }
// 处理不同的异常类型
try {
invocation.invoke();
} catch (ReportException e) {
// 处理 ReportException;
StringBuilder errMsg = new StringBuilder();
errMsg.append("异常触发所属模块:" + e.getModule() + ";");
errMsg.append("异常触发错误代码:" + e.getErrCode() + ";");
errMsg.append("异常触发错误消息:" + e.getErrMsg() + ";");
errMsg.append("异常触发参数列表:" + e.getParams() + ";");
// 打印日志信息
logger.error(errMsg.toString(), e);
controller.renderJson(AjaxResultUtil.error(e.getErrCode(),e.getErrMsg()));
}catch (Exception e) {
// 处理 其余Exception;
logger.error(e.getMessage(), e);
controller.renderJson(AjaxResultUtil.error("后台处理异常,请检查日志"));
}
}
}
在Jfinal主配置文件中加载拦截器
public class MainConfig extends JFinalConfig {
// ------ 其他配置 ------
@Override
public void configInterceptor(Interceptors interceptors) {
// 添加全局控制器拦截器[验证用户登录状态]
interceptors.addGlobalActionInterceptor(new LoginInterceptor());
// 添加全局控制器拦截器[处理全局异常(针对自定义ReportException异常额外处理)]
interceptors.addGlobalActionInterceptor(new GlobalExceptionInterceptor());
// 添加管理员权限拦截器[针对管理员权限进行方法拦截]
}
}
c.常见问题
5.Jfinal热加载-Jrebel插件
jfinal热加载:https://blog.csdn.net/qq_35868412/article/details/90058096
激活参考:https://www.2loveyou.com/articles/2020/01/09/1578533228431.html
https://jrebel.qekang.com/
https://jrebel.qekang.com/4571ab86-eb0d-4d2b-999e-37406bb8ba38
直接ip访问可能出错
参考使用:http://www.jfinal.com/share/556
JFinal入门项目学习-用户管理系统
1.功能需求
2.创建流程
【1】数据库创建
【2】项目创建、配置
项目配置过程中如果出现没有找到指定的部分注解、方法,则考虑是否jfinal的版本较低导致(利用JBolt插件生成的项目使用的插件版本可能不是最新的,自己要调整一下,亦或是配置文件配置出错)
a.Model生成
创建相应的maven项目,此处借助JBolt插件完成(利用JBolt自动生成Model实体)项目创建,Generator执行完成可看到项目生成相应的model,以及_MappingKit类,则需要在MainConfig(自定义程序配置文件)文件中解开相关注释,并在web.xml中确认MainConfig的配置信息是否相对应
项目配置完成可以启动一下,查看是否配置成功
b.Controller创建
创建一个UserController进行测试,随后在MainConfig配置文件中配置对应Controller映射,通过“localhost/映射名称/方法名称”进行访问,此处为“localhost/user/list”
访问成功数据显示如下内容:数据库的数据被转化成JSON格式显示在页面上
c.数据分页(前后端实现)
引入前端框架LayUI,创建目录格式:webapp下创建res文件夹用于存放layui相关的文件,随后在webapp下的WEB-INF文件夹下创建一个user文件夹用于存放user相关的jsp文件,从LayUI官网上下载有关数据表格的代码,替换相关信息即可
随后将jsp文件内的“渲染方法”对应调整为user相关的信息
一般开发的时候是通过Service包装方法,随后在controller层进行调用,将数据传送至前端页面
此处需要先在layui官方文档中查看数据表格的数据格式,随后在controller进行封装
使用jetty服务器进行测试(要按照步骤进行配置,不要混淆三种服务器的配置方案),此处访问的路径是http://localhost:8088/JFinal_Demo/user/list_user.jsp(需要注意如果是将相关的jsp文件放置在webapp的WEB-INF目录下,则相应目录无法直接访问,需要配置路径映射,否则出现404错误,此处为了方便调试直接按将相关jsp文件放置在webapp目录下进行测试,所以访问路径参考上述内容),但却无法访问到Controller