目录
1、拦截器介绍
2、Interceptor和Filter的区别
3、如何使用
4、拦截器实现方法
5、工作流程
6、如何判断用户登录
Spring MVC 拦截器(Interceptor)是在请求处理的过程中,能够拦截并干预请求的一种机制。拦截器通常用于在请求到达控制器之前或之后执行一些额外的逻辑操作,比如权限检查、日志记录、用户身份验证等。拦截器是 Spring MVC 框架提供的一种强大工具,用于实现横切关注点(Cross-cutting Concerns)的逻辑。
Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方
法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。
以下是一些关键的概念和特点,以及如何在 Spring MVC 中使用拦截器:
拦截器(Interceptor)和过滤器(Filter)是在 Java Web 应用中用于处理请求和响应的两种不同的机制,它们有一些区别和特点:
虽然拦截器和过滤器在某些功能上有一些重叠,但它们的设计目标和使用场景不同。在实际应用中,你可以根据需要选择使用拦截器或过滤器,或者在某些情况下结合使用它们来实现不同层次的处理和逻辑。
自定义拦截器三个步骤:
① 创建拦截器类实现HandlerInterceptor接口
MyInterceptor1:
package com.xzl.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 逐梦苍穹
*/
public class MyInterceptor1 implements HandlerInterceptor {
@Override
//在目标方法执行之前 执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
System.out.println("preHandle ①");
String param = request.getParameter("param");
if ("yes".equals(param)) {
return true;
} else {
request.getRequestDispatcher("/error.jsp").forward(request, response);
return false;//返回true代表放行 返回false代表不放行
}
}
@Override
//在目标方法执行之后 视图对象返回之前执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
modelAndView.addObject("name", "逐梦苍穹");
System.out.println("postHandle ①");
}
@Override
//在流程都执行完毕后 执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("afterCompletion ①");
}
}
MyInterceptor2:
package com.xzl.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyInterceptor2 implements HandlerInterceptor {
@Override
//在目标方法执行之前 执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
System.out.println("preHandle ②");
return true;
}
@Override
//在目标方法执行之后 视图对象返回之前执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("postHandle ②");
}
@Override
//在流程都执行完毕后 执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("afterCompletion ②");
}
}
② 在spring-mvc.xml中配置拦截器
拦截器的执行顺序取决于配置文件中的配置顺序
③ 测试拦截器的拦截效果
方法名 |
参数 |
功能说明 |
preHandle |
HttpServletRequest request, HttpServletResponse response, Object handler |
在请求到达控制器之前调用,用于权限验证等逻辑。 如果返回 true,请求继续流向控制器;否则中断请求。 |
postHandle |
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView |
在控制器方法执行后、视图渲染之前调用, 可以修改模型数据或添加通用数据。 |
afterCompletion |
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex |
在视图渲染后调用,用于清理资源、处理异常等操作。 |
当同时出现Filter、DispatcherServlet、Interceptor的时候,执行流程如下:
在一个 web 应用中,判断用户是否登录是非常常见的需求,通常可以通过以下几种方法来实现:
无论选择哪种方法,都需要根据项目的需求和安全性来做出适当的决策。通常情况下,Session 管理和 Token 验证是比较常用的方式。在具体实现中,您可以结合框架、库或者自行编写代码来实现用户登录的判断和管理逻辑。
在项目中如何实现:
把对session域中的用户对象校验放在SpringMVC的Interceptor当中。
当客户端请求资源的时候,自动把请求拦截到拦截器当中,开始判断session域中是否存在user对象,如果存在则放行,如果不存在则重定向到登录页面。
可以在我之前发布过的这个项目的基础上加上SpringMVC拦截器操作:
黑马程序员SpringMVC练手项目_逐梦苍穹的博客-CSDN博客https://blog.csdn.net/qq_60735796/article/details/132126823
下面是拦截器以及三层架构中对应的代码实现:
LoginInterceptor:
package com.xzl.interceptor;
import com.xzl.domain.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* @author 逐梦苍穹
* @date 2023/8/12 21:47
*/
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession httpSession = request.getSession();
System.out.println(httpSession);
User user = (User) httpSession.getAttribute("user");
if (user == null){
System.out.println(request.getContextPath());
response.sendRedirect(request.getContextPath() + "/login.jsp");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
UserController:
/**
* @author 逐梦苍穹
* @date 2023/8/5 21:19
*/
@Controller
@RequestMapping(value = "/User")
public class UserController {
@Autowired
@Qualifier(value = "userService")
private UserService userService;
@RequestMapping(value = "/login")
public String login(String username, String password, HttpSession httpSession) {
User user = userService.login(username,password);
if(user!=null){
//登录成功 将user存储到session
httpSession.setAttribute("user",user);
return "redirect:/index.jsp";
}
return "redirect:/login.jsp";
}
}
UserServiceImpl:
/**
* @author 逐梦苍穹
* @date 2023/8/5 21:25
*/
@Service(value = "userService")
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier(value = "userDao")
private UserDao userDao;
@Override
public User login(String username, String password) {
try {
return userDao.findByUsernameAndPassword(username, password);
}catch (Exception e) {
return null;
}
}
}
UserDaoImpl:
/**
* @author 逐梦苍穹
* @date 2023/8/5 21:30
*/
@Repository(value = "userDao")
public class UserDaoImpl implements UserDao {
@Autowired
@Qualifier(value = "jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Override
public User findByUsernameAndPassword(String username, String password) {
return jdbcTemplate.queryForObject("select * from sys_user where username=? and password=?", new BeanPropertyRowMapper(User.class), username, password);
}
}