美文网首页SpringBoot
SpringBoot(三、监听器,拦截器,过滤器,模板引擎)

SpringBoot(三、监听器,拦截器,过滤器,模板引擎)

作者: 强某某 | 来源:发表于2019-05-13 18:48 被阅读0次

    Servlet(3.0)相关

    过滤器(Filter)

    SpringBoot启动默认加载的Filter

    • characterEncodingFilter
    • hiddenHttpMethodFilter
    • httpPutFormContentFilter
    • requestContextFilter

    Filter优先级

    Ordered.HIGHEST_PRECEDENCE: Interget.MIN_VALUE

    Ordered.LOWEST_PRECEDENCE: Interget.MAX_VALUE

    低位值意味着更高的优先级(Higher values are interpreted as lower priority)
    自定义Filter,避免和默认的Filter优先级一样,不然会冲突

    自定义Filter

    1. 使用Servlet3.0的注解进行配置
    2. 启动类里面增加 @ServletComponentScan,进行扫描
    3. 新建一个Filter类,implements Filter,并实现对应的接口
    4. @WebFilter 标记一个类为filter,被spring进行扫描urlPatterns:拦截规则,支持
    5. 控制chain.doFilter的方法的调用,来实现是否通过放行
    • 不放行,web应用resp.sendRedirect("/index.html");

    • 场景: 权限控制、用户登录(非前端后端分离场景)等

    @SpringBootApplication
    @ServletComponentScan
    public class HelloApplication {
        public static void main(String[] args) {
            SpringApplication.run(HelloApplication.class);
        }
    }
    
    @WebFilter(urlPatterns = "/v1/*",filterName = "loginFilter")
    public class LoginFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("容器加载时候调用");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest req= (HttpServletRequest) servletRequest;
            HttpServletResponse res= (HttpServletResponse) servletResponse;
            String name = req.getParameter("name");
            if (!(name==null)) {
                filterChain.doFilter(servletRequest,servletResponse);
            }
            //不执行doFilter则请求直接中止
        }
    
        @Override
        public void destroy() {
            System.out.println("容器销毁的时候调用");
        }
    }
    

    Servlet

    @WebServlet(name = "userServlet",urlPatterns = "/test/customs")
                public class UserServlet extends HttpServlet{
                     @Override
                     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                         resp.getWriter().print("custom sevlet");
                         resp.getWriter().flush();
                         resp.getWriter().close();
                     }
                     @Override
                     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                         this.doGet(req, resp);
                     }
                }
    

    Application上面也要添加@ServletComponentScan

    监听器

    常用的监听器:

    servletContextListener(容器上下文监听器,包含初始化和销毁)、

    httpSessionListener(针对一次完整的会话)、

    servletRequestListener(针对每次请求的初始化和销毁)

    @WebListener
    public class RequestListener implements ServletRequestListener {
        @Override
        public void requestDestroyed(ServletRequestEvent sre) {
            // TODO Auto-generated method stub
            System.out.println("======requestDestroyed 请求销毁========");
        }
        @Override
        public void requestInitialized(ServletRequestEvent sre) {
            System.out.println("======requestInitialized 请求到达========");    
        }
    }
    

    拦截器(SpringMVC)

    • @Configuration
      继承WebMvcConfigurationAdapter(SpringBoot2.X之前旧版本)

    SpringBoot2.X 新版本配置拦截器 implements WebMvcConfigurer

    • 自定义拦截器 HandlerInterceptor

      • preHandle:调用Controller某个方法之前
      • postHandle:Controller之后调用,视图渲染之前,如果控制器Controller出现了异常,则不会执行此方法afterCompletion:不管有没有异常,这个afterCompletion都会被调用,用于资源清理
    • 按照注册顺序进行拦截,先注册,先被拦截

      拦截器不生效常见问题:

      • 是否有加@Configuration
      • 拦截路径是否有问题 ** 和 *
      • 拦截器最后路径一定要 “/*”, 如果是目录的话则是 //

    定义拦截器

    //这样下面就不用添加log的初始化
    @Slf4j
    @Component  //是为了把拦截器交给spring管理,这样在下面的MvcConfig中就不需要@Bean那个了,直接@Autowired即可
    public class MyInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            log.info("执行");
            return true;
        }
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        }
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    
        }
    }
    

    添加java配置

    @Configuration
    public class MvcConfig implements WebMvcConfigurer{
        /**
         * 通过@Bean注解,将我们定义的拦截器注册到Spring容器
         * @return
         */
        @Bean
        public LoginInterceptor loginInterceptor(){
            return new LoginInterceptor();
        }
        /**
         * 重写接口中的addInterceptors方法,添加自定义拦截器
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 通过registry来注册拦截器,通过addPathPatterns来添加拦截路径
            registry.addInterceptor(this.loginInterceptor()).addPathPatterns("/**");
        }
    }
    

    拦截器(spring)和过滤器(servlet)的关系

    是基于函数回调 doFilter(),而Interceptor则是基于AOP思想

    Filter在只在Servlet前后起作用,而Interceptor够深入到方法前后、异常抛出前后等

    依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境。

    在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。

    Filter和Interceptor的执行顺序: 过滤前->拦截前->action执行->拦截后->过滤后

    常用启动器

    启动器官网

    • spring-boot-starter-web
    • spring-boot-starter-activemq
    • spring-boot-starter-aop
    • spring-boot-starter-data-redis
    • spring-boot-starter-freemarker
    • spring-boot-starter-thymeleaf
    • spring-boot-starter-webflux

    模板引擎

    模板引擎比较

    1、JSP(后端渲染,消耗性能)

    2、Freemarker

    • FreeMarker Template Language(FTL) 文件一般保存为 xxx.ftl
    • 严格依赖MVC模式,不依赖Servlet容器(不占用JVM内存)
    • 内建函数

    3、Thymeleaf (主推)

    • 轻量级的模板引擎(负责逻辑业务的不推荐,解析DOM或者XML会占用多的内存)可以直接在浏览器中打开且正确显示模板页面
    • 直接是html结尾,直接编辑 xdlcass.net/user/userinfo.html
    • 因为支持浏览器直接打开,所以前后端可以并行开发

    整合模板引擎freemarker

    1、Freemarker相关maven依赖

    <!-- 引入freemarker模板引擎的依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
    

    2、Freemarker基础配置

    # 是否开启thymeleaf缓存,本地为false,生产建议为true
    spring.freemarker.cache=false
    spring.freemarker.charset=UTF-8
    spring.freemarker.allow-request-override=false
    spring.freemarker.check-template-location=true
    
    #类型
    spring.freemarker.content-type=text/html
    spring.freemarker.expose-request-attributes=true
    spring.freemarker.expose-session-attributes=true
    
    #文件后缀
    spring.freemarker.suffix=.ftl
    #路径
    spring.freemarker.template-loader-path=classpath:/templates/
    

    3、建立文件夹

    • src/main/resources/templates/fm/user/
    • 建立一个index.ftl
    • user文件夹下面建立一个user.html

    整合模板引擎thymeleaf

    官网地址
    1、thymeleaf相关maven依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    

    2、thymeleaf基础配置

    #开发时关闭缓存,不然没法看到实时页面
    spring.thymeleaf.cache=false
    spring.thymeleaf.mode=HTML5
    #前缀
    spring.thymeleaf.prefix=classpath:/templates/
    #编码
    spring.thymeleaf.encoding=UTF-8
    #类型
    spring.thymeleaf.content-type=text/html
    #名称的后缀
    spring.thymeleaf.suffix=.html
    

    3、建立文件夹

    • src/main/resources/templates/tl/
    • 建立一个index.html

    4、简单测试代码编写和访问

    注意:$表达式只能写在th标签内部

    快速入门

    相关文章

      网友评论

        本文标题:SpringBoot(三、监听器,拦截器,过滤器,模板引擎)

        本文链接:https://www.haomeiwen.com/subject/atgraqtx.html