拦截器
方法一、实现 Filter 接口
不需要再写其它的代码,配置用注解就解决了(个人比较喜欢用这个,多个拦截器的话就设置优先级)
1、实现javax.servlet包下的Filter接口
2、@Order(可选,有多个过滤器时可添加)注解,@Order用于控制过滤器的级别,值越小级别越高
3、过滤的业务逻辑写在doFilter()方法中。
import java.io.IOException;
import java.util.Arrays;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@Component
@Order(1)//控制过滤器的级别(一个过滤器的话就不用写了)值越小优先级越高
@WebFilter(urlPatterns="/**",filterName="loginFilter") //有了该注解,无需再写什么配置类什么的
public class LoginFilter implements Filter{
//排除不拦截的url
private static final String[] excludePathPatterns = {
"/", //首页
"/favicon.ico", //网页图标
"/one",
"/two"
};
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("拦截器调用 init ");
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
String url = req.getRequestURI();
System.out.println("此次请求地址为: "+url);
if (Arrays.asList(excludePathPatterns).contains(url)) {
System.out.println("该请求放行");
chain.doFilter(request, response);
}else {
System.out.println(url+" 请求被拦截了。");
}
}
@Override
public void destroy() {
System.out.println("拦截器调用 destroy ");
// TODO Auto-generated method stub
}
}
方法二、继承HttpFilter类
可以从源码里看出 它有两个方法实现
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
两者的区别个人觉得就是ServletRequest 与HttpServletRequest 的区别,他们的功能还是有一些区别的,比如HttpServletRequest 可以查看请求的url,而ServletRequest 不行。其他都和方法一 一模一样
方法三、实现 HandlerInterceptor 接口
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class LoginInterceptor implements HandlerInterceptor {
/**
* 预处理回调方法,实现处理器的预处理
* 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/**
* 这里面写逻辑判断语句,与Filter不同的是,能到达这里的请求都是我们 拦截 的请求
*
* 处理后 return true 则继续请求;(继续执行)
* return false;则将请求拦截下来
*/
return false;
}
/**
* 后处理回调方法,实现处理器(controller)的后处理,但在渲染视图之前
* 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
/**
* 整个请求处理完毕回调方法,即在视图渲染完毕时回调,
* 如性能监控中我们可以在此记录结束时间并输出消耗时间,
* 还可以进行一些资源清理,类似于try-catch-finally中的finally,
* 但仅调用处理器执行链中
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// TODO Auto-generated method stub
}
}
同时,我们还需要写一个配置类实现
import com.springboot_ssm_web.filter.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Autowired
private LoginInterceptor loginInterceptor;
/**
添加不需要拦截的请求
*/
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
.excludePathPatterns(
"/", //首页
"/favicon.ico", //网页图标
"/one",
"/two"
);
super.addInterceptors(registry);
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/","classpath:/public/","classpath:/resources/");
super.addResourceHandlers(registry);
}
这句话是告诉它你的资源目录。
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/","classpath:/public/","classpath:/resources/");
我的目录结构如下

public,resources是我自己建的(这个不能随便建的,具体请看 https://www.jianshu.com/p/ac54d4f43e66)
再附上一个小例子,HandlerInterceptor拦截登陆的实现(个人喜欢 实现 Filter 接口 来实现功能,HandlerInterceptor也是最近才开始)
@Component
public class MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String name= (String) request.getSession().getAttribute("LoginUserame");
if (!name.isEmpty()){
request.getRequestDispatcher("/main.html").forward(request,response);
return false;
}else {
request.getRequestDispatcher("/login.html").forward(request, response);
return true;
}
}
}
@Controller
public class HelloController {
@RequestMapping("login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password, HttpSession session){
if (username.equals("123")&password.equals("123")){
session.setAttribute("LoginUserame",username);
return "redirect:main";
}else{
return "login";
}
}
}
网友评论