SpringBoot 自定义filter 和 interceptor,自定义静态文件存放位置

上篇分享我们已经有了一个最基础具有登陆验证功能 的SpringBoot web项目,本篇对照之前SpringMVC 的xml配置,阐述SpringBoot 中的filter 和 interceptor。

一、web.xml中的filter 和 SpringBoot filter 比较。

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

在SpringBoot 中我们定义一个filter:

package cn.pw.pf.web.filter;


import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * 自定义Filter
 * Login Filter
 * @Description:
 * @Author:libin
 * @Date: Created in 16:40 2017/11/13
 */
@WebFilter(filterName = "myFilter",urlPatterns = "/*")
@Order(1)
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("filter======> 我是过滤器!");
        chain.doFilter(request,response);
    }

    @Override
    public void destroy() {

    }
}

@WebFilter 是自定义Filter的关键注解,属性filterName 相当于web.xml中的 <filter-name>;属性urlPatterns 相当于web.xml中的<url-pattern>
@Order(1)在定义多个Filter时,用于决定执行顺序的,数字越小,越先执行。

说明:本篇以web.xml的CharacterEncodingFilter为例,但在SpringBoot中CharacterEncodingFilter有更简单的配置,在application.xml中做如下配置便可 :

spring:
  http:
    encoding:
      charset: UTF-8
      enabled: true
      force: true

言归正传,我们启动项目测试一下过滤器是否 生效:
在浏览器分别打开 http://localhost:8680/hellohttp://localhost:8680/login ,观察控制台输出,如果不出意外,控制台连续输出了 “filter======> 我是过滤器!”,看来我们的过滤器生效了,我们还可以将urlPatterns 设置 为 /hello ,这样只有访问 http://localhost:8680/hello 时,控制台才会输出 “filter======> 我是过滤器!”。

二、spring-mvc.xml中的 interceptor 和SpringBoot interceptor 比较

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/static/**" />           
            <bean class="cn.pw.pf.web.filter.MyInterceptor" />
        </mvc:interceptor>
</mvc:interceptors>

上面的配置不用解释,先在filter包下编写一个MyInterceptor类。

package cn.pw.pf.web.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器
 * @Description:
 * @Author:libin
 * @Date: Created in 17:46 2017/11/13
 */
@Component
public class MyInterceptor implements HandlerInterceptor {

    Logger logger = LoggerFactory.getLogger(MyInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("执行preHandle==============》");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        logger.info("执行postHandle==============》");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.info("执行afterCompletion==============》");
    }
}

下面我们看在SpringBoot中如何让自定义的拦截器MyInterceptor 生效

package cn.pw.pf.web.filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 配置自定义拦截器
 * @Description:
 * @Author:libin
 * @Date: Created in 17:41 2017/11/13
 */
@Configuration
public class MyWebConfig extends WebMvcConfigurerAdapter{

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
                           registry.addInterceptor(myInterceptor).addPathPatterns("/*").excludePathPatterns("/hello/**");
        super.addInterceptors(registry);
    }
}

阅读上面的代码,我们不难发现,主要在重写WebMvcConfigurerAdapter的addInterceptors方法上,addPathPatterns添加了要拦截的路径,excludePathPatterns添加了排除的路径。
我们重启项目,测试一下,访问 http://localhost:8680/login ,也可以在login界面点击登录。
测试结果,我们分析任何一次访问都经过了filter和interceptor。

filter======> 我是过滤器!
cn.pw.pf.web.filter.MyInterceptor : 执行preHandle==============》
cn.pw.pf.web.filter.MyInterceptor : 执行postHandle==============》
cn.pw.pf.web.filter.MyInterceptor : 执行afterCompletion==============》

我们再访问排除的URL是否生效,打开 http://localhost:8680/hello ,页面上显示出了内容,控制台只是输出了

filter======> 我是过滤器!

我们排除掉的”/hello/**”,拦截器不再拦截它,测试顺利通过!
有同学就问了,你为什么不按spring-mvc.xml中一样 ,排除 static 资源。原因很简单,SpringBoot默认不拦截所有的静态资源,如果不信,可以 直接访问 http://localhost:8680/css/common.css 试试。

说明:SpringBoot把类路径下的/static,/public,/resources和META-INF/resources文件下的静态文件映射为了 “/”,可以直接访问,我们也可以根据下面的方法自定义静态文件的存放位置。

三、自定义静态文件存放 位置,只需在MyWebConfig 中,重写addResourceHandlers方法。

@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/img/**").addResourceLocations("classpath:/img/");
        super.addResourceHandlers(registry);
    }

这样,我们就定义了一个和static平级的文件夹img用来存放图片,随便丢一张 图片no.jpg进去,然后带上路径访问:
http://localhost:8680/img/no.jpg

OK,今天的分享就到此结束了,SpringBoot的基础使用就分享这么多,很简单。

到今天互联网迸发的时代,微服务已是大势所趋,只有在 SpringCloud 微服务架构下,使用SpringBoot才是开发人员值得研究的方向。如果有人想深入了解SpringBoot ,我推荐《java EE 开发的颠覆者 Spring Boot 实战》这本书。但是,初学的读者一定要注意,这本书是在SpringBoot 1.3版本的基础上讲解的,想实践书中的例子,一定要用对版本,要不会很苦恼。

后面的分享,我将开启新的篇章,结合SpringCloud 、Eureka、等,逐步由简入深,来完成一个基于微服务框架的简单demo,帮助初学者快速上手。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值