• IDEA项目搭建十一——添加拦截器、忽略URL大小写、启动事件


    程序启动时如果需要添加某些初始化代码可以使用以下事件处理

    import org.springframework.context.ApplicationEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.stereotype.Component;
    
    /**
     * 程序初始化事件
     */
    @Component
    public class ApplicationEventListener implements ApplicationListener {
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
    //        if (event instanceof ApplicationEnvironmentPreparedEvent) {
    //            // 初始化环境变量
    //        }else if(event instanceof ApplicationPreparedEvent){
    //            // 初始化完成
    //        }else if (event instanceof ContextRefreshedEvent) {
    //            // 应用刷新
    //        }else if (event instanceof ApplicationReadyEvent) {
    //            // 应用已启动完成
    //        }else if (event instanceof ContextStartedEvent) {
    //            // 应用启动,需要在代码动态添加监听器才可捕获
    //        }else if (event instanceof ContextStoppedEvent) {
    //            // 应用停止
    //        }else if (event instanceof ContextClosedEvent) {
    //            // 应用关闭
    //        }else {}
        }
    }

    过滤用户登录状态验证时普遍使用拦截器或过滤器spring boot 2.0使用以下方式

    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 请求拦截器
     * 参考资料:https://www.cnblogs.com/holly8/p/6178828.html
     * 普遍继承HandlerInterceptorAdapter抽象类,其中多提供了一个异步拦截方法afterConcurrentHandlingStarted(),我们用不到所以直接实现基础接口
     * 调用顺序:preHandler(可多个) -> Controller -> postHandler(可多个) -> model渲染-> afterCompletion(可多个)
     */
    public class RequestInterceptor implements HandlerInterceptor {
    
        /**
         * Action执行前调用
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            try {
                System.out.println("调用拦截器");
                //判断用户会话状态
                if (0 > 0) {
                    System.out.println("拦截验证-已登录");
                    return true;
                } else {
                    System.out.println("拦截验证-未登录");
                    //根据header标识判断当前请求是否为Ajax请求
                    if (request.getHeader("x-requested-with") == null){
                        //如果不是Ajax请求则重定向
                        response.sendRedirect("/admin");//重定向回登录页
                    }else {
                        //如果是Ajax则更改状态码通知前端
                        //response.sendError(580,"自定义错误");//如果想提示错误并根据配置文件自动跳转到错误页面,则使用sendError
                        response.setStatus(401);//登录异常(401)权限验证不通过(403)如果只是改变状态码自己做后续处理,则使用setStatus
                        /*
                        下面是直译官方API文档的内容:
                        sendError(int sc):使用指定的状态码并清空缓冲,发送一个错误响应至客户端。如果响应已经被提交,这个方法会抛出IllegalStateException。使用这个方法后,响应则应该被认为已被提交,且不应该再被进行写操作了。
                        sendError(int sc, String msg):使用指定的状态码发送一个错误响应至客户端。服务器默认会创建一个HTML格式的服务错误页面作为响应结果,其中包含参数msg指定的文本信息,这个HTML页面的内容类型为“text/html”,
                        保留cookies和其他未修改的响应头信息。如果一个对应于传入的错误码的错误页面已经在web.xml中声明,那么这个声明的错误页面将会优先于建议的msg参数服务于客户端。(ps:相比较上面的方法,我更倾向于前者。
                        使用上面的方法,可以通过定制不同状态的响应结果显示于客户端,我们应该不想让客户端看到服务器创建出的简单粗暴的页面吧?)
                        setStatus(int sc):设置响应的状态码。这个方法被用于当响应结果正常时(例如,状态码为SC_OK或SC_MOVED_TEMPORARTLY)设置响应状态码。如果发生错误,而且来访者希望调用在web应用中定义的错误页面作为显示,
                        那么应该使用sendError方法代替之。使用setStatus方法之后,容器会清空缓冲并设置Location响应头,保留cookies和其他响应头信息。
                        总结:sendError适用于报错且存在对应的报错页面配置作为输出显示的情况,而setStatus适用于正常响应的情况,仅仅可以改变响应状态码而已。
                         */
                    }
                    return false;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * Action执行后,View渲染前调用
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    
        }
    
        /**
         * View渲染后调用,整个流程执行结束调用
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    
        }
    }

     注入拦截器到web中

    import org.springframework.context.annotation.Configuration;
    import org.springframework.util.AntPathMatcher;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * 配置类
     * WebMvcConfigurerAdapter已被废弃,官方推荐改用WebMvcConfigurer
     */
    @Configuration
    public class MyInterceptorConfig implements WebMvcConfigurer {
    
        /**
         * 注入拦截器
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //将拦截器注入进程序,可同时注入多个拦截器
            //registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**");
            /*
            使用addPathPatterns增加拦截规则,使用excludePathPatterns排除拦截规则
            /admin/**:代表http://域名/admin/** 拦截该目录下的所有目录及子目录
            /admin:代表http://域名/admin 仅拦截此形式访问(无法拦截/admin/ 形式)
            /admin/*:代表http://域名/admin/* 拦截该目录的所有下级目录不包含子目录(可以拦截/admin/ 形式)
             */
            registry.addInterceptor(new RequestInterceptor())
                    .addPathPatterns("/admin/**")
                    .excludePathPatterns("/admin")
                    .excludePathPatterns("/admin/*")
                    .excludePathPatterns("/admin/content/**");
        }
    
        /**
         * 注入路径匹配规则
         */
        @Override
        public void configurePathMatch(PathMatchConfigurer configurer) {
            //设置忽略请求URL的大小写
            AntPathMatcher matcher = new AntPathMatcher();
            matcher.setCaseSensitive(false);
            configurer.setPathMatcher(matcher);
            //设置匹配规则
            /*
             setUseSuffixPatternMatch : 设置是否是后缀模式匹配,如“/user”是否匹配/user.*,默认true即匹配
             setUseTrailingSlashMatch : 设置是否自动后缀路径模式匹配,如“/user”是否匹配“/user/”,默认true即匹配
             */
            configurer.setUseSuffixPatternMatch(false).setUseTrailingSlashMatch(true);
        }
    }
  • 相关阅读:
    【Silverlight】Bing Maps学习系列(八):使用Bing Maps Silverlight Control加载自己部署的Google Maps
    Visual Studio 2010在简洁中强调团队合作
    【Silverlight】Bing Maps学习系列(九):自定义功能导航条(Custom NavigationBar)
    Flash OBJECT 和 EMBED 标签
    SWFObject 的原站提供的使用说明
    一篇清楚阐述 JAvaScript 传递数据 到 Flash 的文章
    Flare 的 Edge边上加 Label
    借助 SWFObject 实现利用JavaScript嵌入 Flash
    3种基本的Flash/Javascript通信方式 (转)
    passing data from HTML to Flash
  • 原文地址:https://www.cnblogs.com/taiyonghai/p/9334925.html
Copyright © 2020-2023  润新知