JFinal框架中的web.xml可以实现Filter的解析。
JFinal中的Filter(web.xml,自己写的Filter实现了Filter);
Filter中的详细逻辑可以引入Handler和JFinal中的,Interceptor;
权限问题:
权限问题比较理想的办法是使用 AOP,所以可以选择 Interceptor、Handler或Filter。JFinal提供了 Interceptor与Handler可供选择。
通常情况下使用 Interceptor 比较合适。
Interceptor 中可以方便地获得 actionKey、controllerKey来做权限控制的依据,
还可以使用render控制页面跳转以及使用redirect来重定向。
Handler可以在更高层次来做权限,但失去了 interceptor中在上面提到的好处。
jfinal 的入口是 JFinalFilter,没有使用 servlet , 在 com.jfinal.core 包下面可以找到源代码
Filter:
JFinalFilter和其他的Filter一样,都是实现了Filter接口;
在web.xml中配置Filter可以对所有的请求及响应资源进行拦截过滤,如web.xml中的配置;
filter中的和filter-mapping中的必须一致;
中的类必须是定义的Filter实现类并且填写完成的包名;
是对请求及响应的URL资源拦截过滤。
JFinalFilter类三个方法init(),doFilter(),destroy()及生命周期介绍
1、Filter过滤器都是通过web容器作为实例化基础的,及它们是以web服务器作为容器承托。
2、init和destroy方法在整个生命周期中分别只执行一次:
init是在web容器启动时执行一次,对需要的服务实体进行初始化;
destroy是在web容器关闭是执行一次,对服务实例进行摧毁。
3、doFilter是最重要的方法,
当web应用正常启动之后前台的请求都跳进doFilter方法进行拦截处理,如果需要在Filter进行做文章,即可从此方法入手,doFilter方法中可进行资源链往下跳。
源码分析:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
// 获取 request、response,设置编码
HttpServletRequest request = (HttpServletRequest)req
;
HttpServletResponse response = (HttpServletResponse)res
;
request.setCharacterEncoding(encoding);
// 初始化的时候可以看出 contextPathLength 为 0 或者为 项目名称的长度
// 比如 target = webapp/xx/yy/zz,则截取后的 target = /xx/yy/zz
String target = request.getRequestURI()
;
if
(
contextPathLength
!=
0
) { target = target.substring(
contextPathLength
)
;
}
// 在调用了 ActionHandler的 handle 方法之后,isHandled[0] 才会被置为 true。
boolean[] isHandled = {
false}
;
try
{
// 重头戏,handler 链首到链尾 ActionHandler 依次进行处理
handler
.handle(target
,
request
,
response
,
isHandled)
;
}
catch (Exception e) {
if (log.isErrorEnabled()) {
String qs = request.getQueryString();
log.error(qs == null ? target : target + "?" + qs, e); } }
// 若最后 isHandled[0] = false,会执行下一个 Filter。
if
(isHandled[
0
] ==
false
) {
chain.doFilter(request, response);
}}doFilter是接收HTTP资源请求的方法:
1、首先对request请求进行设置编码;
2、然后获取请求路径,并调用handle方法,调用此方法可以根据请求路径作为key去查找init初始化Controller的Map集合里查找对应的Controller实体并调用对应的处理方法;
3、如果请求路径不满足判断条件(即未找到对应的Controller),会调用chain.doFilter按默认条件寻找下一个资源。
Handler:
doFilter - Handler 链中每个 handler.handle(...)
JFinal 初始化过程中可以 add JFinal 库中的Handler 或自定义的 Handler。
例如:ContextPathHandler,JFinal 自身扩展的 Handler。
访问项目时就会走过 handler 方法设置 contextPath。这样在前端就可以通过 ${CONTEXT_PATH} 得到项目根路径。
ContextPathHandler,JFinal 自身扩展的 Handler。
public class ContextPathHandler extends Handler {
private String contextPathName;
public ContextPathHandler() {
contextPathName = "CONTEXT_PATH";
}
public ContextPathHandler(String contextPathName) {
if (StrKit.isBlank(contextPathName))
throw new IllegalArgumentException("contextPathName can not be blank.");
this.contextPathName = contextPathName;
}
public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
request.setAttribute(contextPathName, request.getContextPath());