JFinal中的Filter,Handler,Interceptor的功能作用

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 init(FilterConfig filterConfig) throws ServletException {
createJFinalConfig(filterConfig.getInitParameter("configClass"));
if (jfinal.init(jfinalConfig, filterConfig.getServletContext()) == false)
throw new RuntimeException("JFinal init error!");
handler = jfinal.getHandler();
constants = Config.getConstants();
encoding = constants.getEncoding();
jfinalConfig.afterJFinalStart();
String contextPath = filterConfig.getServletContext().getContextPath();
contextPathLength = (contextPath == null || "/".equals(contextPath) ? 0 : contextPath.length());
}
1、首先调用init方法进行初始化,调用createJFinalConfig对自定义的JFinalConfig实例化 ,jfilterConfig.getIntParameter('configClass')就是获取web.xml中filter里配置的init-param参数,即一个配置类路径。
2、jfinal.init()方法完成了 配置参数实体Constants、请求编码Encoding、Controller、Interceptor等等的初始化 ,想Controller等都是存放在一个Map集合里。
contextPath获取webRoot路径
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());

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值