过滤器是什么?
它是基于Servlet 技术实现的, 简单的来说,过滤器就是起到过滤的作用,在web项目开发中帮我们过滤一些指定的 url做一些特殊的 处理。
过滤器主要做什么?
过滤掉一些不需要的东西,例如一些错误的请求。
也可以修改请求和相应的内容。
也可以拿来过滤未登录用户
过滤器的代码实现?
过滤器(filter)有三个方法,其中初始化(init)和摧毁(destroy)方法一般不会用到,主要用到的是doFilter这个方法。
怎么过滤呢?
如果过滤通过,则在doFilter执行 filterChain.doFilter(request,response); 。
实现的方式?
自定义Filter有两种实现方式,第一种是使用@WebFilter,第二种是使用 FilterRegistrationBean。
属性名 类型 描述
filterName String 指定该Filter的名称
urlPatterns String 指定该Filter所拦截的URL。
value String 与 urlPatterns 一致
1. 创建一个MyFilter.java实现Filter接口
@WebFilter(urlPatterns = "/api/*",filterName = "myFilter")
@Order(1)//指定过滤器的执行顺序,值越大越靠后执行
public class MyFilter 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 request= (HttpServletRequest) servletRequest;
String uri=request.getRequestURI();
String method=request.getMethod();
System.out.println(uri+" "+method+"哈哈我进入了 MyFilter 过滤器了");
filterChain.doFilter(servletRequest,servletResponse);
}
}
2. 启动类加上 @ServletComponentScan 注解
3. 创建一个 FilterController 接口
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/user/filter")
public String hello(){
return "哈哈我通过了过滤器";
}
}
4.测试
1. 创建 FilterConfig
@Configuration
public class FilterConfig {
@Bean
public MyFilter myFilter(){
return new MyFilter();
}
@Bean
public FilterRegistrationBean getFilterRegistrationBean(MyFilter myFilter){
FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
/**
* 设置过滤器
*/
filterRegistrationBean.setFilter(MyFilter());
/**
* 拦截路径
*/
filterRegistrationBean.addUrlPatterns("/api/*");
/**
* 设置名称
*/
filterRegistrationBean.setName("myFilter");
/**
* 设置访问优先级 值越小越高
*/
filterRegistrationBean.setOrder(1);
return filterRegistrationBean;
}
}
2. 修改 MyFilter.java
//@WebFilter(urlPatterns ={"/api/*"},filterName = "myFilter")
3. 修改启动类
//@ServletComponentScan
4. 测试
1. 修改 application.properties 加入开发接口通配地址
#凡是请求地址层级带有 open 都放行
open.url=/**/open/**
2. 修改 MyFilter
//@WebFilter(urlPatterns ={"/*"},filterName = "myFilter")
public class MyFilter implements Filter {
@Value("${open.url}")
private String openUrl;
@Override
public void init(FilterConfig filterConfig) {
System.out.println("初始化 myFilter 过滤器");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestUrl = request.getRequestURI();
System.out.println("过滤器MyFilter拦截了请求为" + requestUrl);
//首先校验是否是开放 api
//是直接放行,否再校验token
PathMatcher matcher = new AntPathMatcher();
if(matcher.match(openUrl,requestUrl)){
filterChain.doFilter(servletRequest,servletResponse);
}else {
String token=request.getHeader("token");
if(StringUtils.isEmpty(token)){
servletRequest.getRequestDispatcher("/api/open/unLogin").forward(servletRequest,
servletResponse);
}else {
filterChain.doFilter(servletRequest,servletResponse);
}
}
}
}
3. 新增 未登录接口、首页接口
@GetMapping("/open/home/info")
public Map getHome(){
Map map=new HashMap<>();
map.put("游客","欢迎访问首页");
return map;
}
@GetMapping("/open/unLogin")
public String getUnauthorized(){
return "登录失效,请重新登录";
}
通过直接访问开放接口和访问需权鉴接口进行测试
拦截器是什么?
简单的来说,就是一道阀门,在某个方法被访问之前,进行拦截,然后在之前或之后加入某些操作,拦截器是AOP 的一种实现策略。
拦截器主要做什么?
对正在运行的流程进行干预。
拦截器的代码实现。
拦截器也主要有三个方法:
其中preHandle是在请求之前就进行调用,如果该请求需要被拦截,则返回false,否则true;
postHandle是在请求之后进行调用,无返回值;
afterCompletion是在请求结束的时候进行调用,无返回值
步骤:创建一个类实现 HandlerInterceptor 接口,再创建一个配置类实现 WebMvcConfigurer接口 ,重写 addInterceptors 方法。
public class MyInterceptor implements HandlerInterceptor {
@Value("${open.url}")
private String openUrl;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object
handler) throws Exception {
System.out.println("MyInterceptor....在请求处理之前进行调用(Controller方法调用之前)");
String requestUrl=request.getRequestURI();
System.out.println("过滤器MyFilter拦截了请求为"+requestUrl);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object
handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor...请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之
后)");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object
handler, Exception ex) throws Exception {
System.out.println("MyInterceptor....在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对
应的视图之后执行(主要是用于进行资源清理工作)");
}
}
#开放性接口
open.url=/**/open/**
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Value("${open.url}")
private String openUrl;
@Bean
public MyInterceptor getMyInterceptor(){
return new MyInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getMyInterceptor()).addPathPatterns("/api/**").excludePathPatterns(openUrl
);
}
}
@RestController
@RequestMapping("/api")
public class InterceptorController {
@GetMapping("/home/open/info")
public String home(){
return "欢迎来到首页";
}
@GetMapping("/user/interceptor")
public String interceptor(){
return "我被拦截了并通过了拦截器";
}
}
带有open http://localhost:8080/api/open/home/info 不拦截
其他没通过公开接口访问的都会被拦截
默认的静态资源路径为:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public
只要静态资源放在这些目录中任何一个,SpringMVC都会帮我们处理。 我们习惯会把静态资源放在classpath:/static/ 目 录下。
1. 把 test.png 图片放入 static 文件夹
2.访问