过滤器,拦截器,监听器具体应用上的区别

过滤器filter
过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集, 或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话)。

最常用的过滤器就是登陆过滤器LoginFilter,过滤器一般都是继承Filter 接口

public class LoginFilter extends HttpServlet implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        HttpSession session = req.getSession();
        if(session.getAttribute("").equals("")){

        }
        String url = req.getServletPath();
        String contextPath = req.getContextPath();
        res.sendRedirect(contextPath + "/jspPage/login.jsp");
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

拦截器interceptor:
进行权限验证,或者是来判断用户是否登陆,日志记录,或者限制时间点访问。我自己用过拦截器,是用户每次登录时,都能记录一个登录时间。 (这点用拦截器明显合适,用过滤器明显不合适,因为没有过滤任何东西)

public class EntranceInterceptor extends HandlerInterceptorAdapter {  

    private Logger LOG = Logger.getLogger(EntranceInterceptor.class);  

    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  

        MDC.put(LogUtil.KEY_REQUEST_ID, RandomStringUtils.randomAlphanumeric(8));  
        LOG.debug(LogUtil.getLogStr(request));  

        //过滤掉静态资源  
        if(handler instanceof HandlerMethod){  

            //获取游戏  
            String url = request.getRequestURI();  
            if(!"".equals(url) && !"/".equals(url)){  
                String str = url.substring(url.indexOf("/") + 1);  
                StringTokenizer st = new StringTokenizer(str, "/");  

                String game = "";  
                int c = 0;  
                while (st.hasMoreTokens()) {  
                    if(++c == 2){  
                        game = st.nextToken();  
                    }  
                    st.nextToken();  
                }  
                LOG.debug(LogUtil.getLogStr("[当前访问活动名称]:[" + game + "]"));  
                TempleConfigContext.setCurrentGameActivity(GameActivityEnum.getGameActivityEnum(game));  
            }  

            //是否有AjaxAnno注解  
            HandlerMethod method = (HandlerMethod) handler;  
            AjaxAnno anno = method.getBean().getClass().getAnnotation(AjaxAnno.class);  
            if (anno != null || (anno = method.getMethod().getAnnotation(AjaxAnno.class)) != null) {  
                TempleConfigContext.setCurrentRequestType(TempleConfigContext.AJAX_REQUEST_TYPE);  
            }  

            LoginRequired required = method.getBean().getClass().getAnnotation(LoginRequired.class);  
            if (required != null || (required = method.getMethod().getAnnotation(LoginRequired.class)) != null) {  
                //验证是否登录  
                GameActivityEnum activity = TempleConfigContext.getCurrentGameActivity();  
                if (request.getSession().getAttribute(activity.getActivity() + "_" + Constant.MANAGER_SESSION_LOGIN_USER) == null) {// 判断session里是否有用户信息  
                    throw new BusinessException(CommonStateEnum.BADREQ_PARA_SESSION_TIMEOUT, "您还没有登录或者您的登录已经过期");  
                }  
            }  

            PassAction pass = method.getBean().getClass().getAnnotation(PassAction.class);  
            if (pass == null && (pass = method.getMethod().getAnnotation(PassAction.class)) == null) {  
                //验证是否过期  
                Date[] limit = Constant.getHdLimitTime(TempleConfigContext.getCurrentGameActivity().getActivity());   
                if(null != limit){  
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                    Date date = new Date();  
                    if(null != limit[0] && date.before(limit[0])){  
                        CommonStateEnum error = CommonStateEnum.BADREQ_API_HD_NOT_SATRT;  
                        throw new BusinessException(error, error.getMessage(sdf.format(limit[0])));  
                    }  

                    if(null != limit[1] && date.after(limit[1])){  
                        CommonStateEnum error = CommonStateEnum.BADREQ_API_HD_ALREADY_END;  
                        throw new BusinessException(error, error.getMessage(sdf.format(limit[0]), sdf.format(limit[1])));  
                    }  
                }  
            }             
        }  

        return true;  
    }  

    @Override  
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {  

    }  

    @Override  
    public void afterCompletion(HttpServletRequest request,  
            HttpServletResponse response, Object handler, Exception ex)  
            throws Exception {  
        MDC.remove(LogUtil.KEY_REQUEST_ID);  
    }  
}  

监听器listener
当你要触发一个事件,但这件事既不是过滤,又不是拦截,那很可能就是监听! 联想到Windows编程里的,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。监听器的概念类似于这些。

public final class Log4jConfigListener implements ServletContextListener {
    /**
     * 配置文件位置
     */
    public final String CONFIG_LOCATION_PARAM = "log4jConfigLocation";
    /**
     * 日志文件存放位置
     */
    public final String LOG_DIR = "logDir";
    /**
     * root log 记录级别
     */
    public final String ROOT_LOG_LEVEL = "rootLogLevel";

    public final String CONSOLE_LOGGIN_LEVEL = "consoleLogginLevel";

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        final ServletContext context = sce.getServletContext();
        initProperty(context);
        String location = context.getInitParameter(CONFIG_LOCATION_PARAM);
        location = getRealPath(context, location);
        initLogging(location);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        LogManager.shutdown();
    }

    public String getRealPath(ServletContext servletContext, String path) {
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        String realPath = servletContext.getRealPath(path);
        if (realPath == null) {
            throw new RuntimeException(
                    "ServletContext resource [" + path + "] cannot be resolved to absolute file path - " +
                            "web application archive not expanded?");
        }
        return realPath;
    }

    public void initProperty(ServletContext context) {
        String logDir = context.getInitParameter(LOG_DIR);
        String rootLogLevel = context.getInitParameter(ROOT_LOG_LEVEL);
        String consoleLogginLevel = context.getInitParameter(CONSOLE_LOGGIN_LEVEL);
        if (logDir == null || logDir.startsWith("${") || (System.getProperty("os.name").startsWith("Windows") && logDir.startsWith("/")))
            logDir = System.getProperty("user.home") + "/logs/";
        System.setProperty("LOG_DIR", logDir);
        if (rootLogLevel == null || rootLogLevel.startsWith("${")) {
            rootLogLevel = "INFO";
        }
        System.setProperty("ROOT_LOG_LEVEL", rootLogLevel);
        if (consoleLogginLevel == null || consoleLogginLevel.startsWith("${")) {
            consoleLogginLevel = "INFO";
        }
        System.setProperty("CONSOLE_LOGGIN_LEVEL", consoleLogginLevel);
    }

    public void initLogging(String location) {
        if (location.toLowerCase().endsWith(".xml")) {
            DOMConfigurator.configure(location);
        } else {
            PropertyConfigurator.configure(location);
        }
    }

这些例子都是引用了spring MVC框架中的类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值