SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
**过滤器与拦截器的区别:**拦截器是AOP思想的具体应用。
过滤器
拦截器
想要自定义拦截器,必须实现 HandlerInterceptor 接口
在web项目中
1、配置web.xml 和 springmvc-servlet.xml 文件
2、编写一个拦截器
package com.sangyu.config;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author sangYu
* @date 2023/3/10
*/
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("=============处理前=============");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("=============处理后=============");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("=============清理=============");
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.sangyu.config.MyInterceptor"/>
mvc:interceptor>
mvc:interceptors>
package com.sangyu.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author sangYu
* @date 2023/3/10
*/
@RestController
public class MyTest01 {
@RequestMapping("/t1")
public String test01(){
System.out.println("现在这个test01执行啦");
return "test01";
}
}
<%--
Created by IntelliJ IDEA.
User: 19401
Date: 2023/3/10
Time: 16:20
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$title>
head>
<body>
<h1><a href="${pageContext.request.contextPath}/goLogin">登录a>h1>
<h1><a href="${pageContext.request.contextPath}/goSuccess">首页a>h1>
body>
html>
<%--
Created by IntelliJ IDEA.
User: 19401
Date: 2023/3/10
Time: 17:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form action="${pageContext.request.contextPath}/login">
用户名: <input name="username" type="text">
密码: <input name="password" type="text">
<input type="submit" value="提交">
form>
body>
html>
<%--
Created by IntelliJ IDEA.
User: 19401
Date: 2023/3/10
Time: 17:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
${user}
<a href="${pageContext.request.contextPath}/logout">注销a>
body>
html>
package com.sangyu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
/**
* @author sangYu
* @date 2023/3/10
*/
@Controller
public class LoginController {
/**
* 获取到login页面
* @return login.jsp;
*/
@RequestMapping("/goLogin")
public String goLogin(){
return "login";
}
/**
* 获取到登录成功页面
* @return success.jsp;
*/
@RequestMapping("/goSuccess")
public String goMain(){
return "success";
}
/**
* 登录请求
* @return success.jsp;
*/
@RequestMapping("/login")
public String login(String username, String password, HttpSession httpSession){
//向session记录用户身份信息
System.out.println("接收到数据:"+username);
httpSession.setAttribute("user",username);
return "success";
}
/**
* 退出登录
* @param session;
* @return login.jsp;
* @throws Exception;
*/
@RequestMapping("logout")
public String logout(HttpSession session) throws Exception {
// session 过期
session.invalidate();
return "login";
}
}
但是我们发现一个问题,在index.jsp页面中,我们不点击登录,直接点击首页,也能够跳转到success.jsp页面,这是很不合理的,所以我们需要加上拦截器来判断登录状态
package com.sangyu.config;
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 sangYu
* @date 2023/3/11
*/
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果是登陆页面则放行
System.out.println("uri: " + request.getRequestURI());
if (request.getRequestURI().contains("login")) {
return true;
}
HttpSession session = request.getSession();
// 如果用户已登陆也放行
if(session.getAttribute("user") != null) {
return true;
}
// 用户没有登陆跳转到登陆页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.sangyu.config.LoginInterceptor"/>
mvc:interceptor>
mvc:interceptors>
此时,我们在index.jsp页面点击首页,就不会直接进入success.jsp页面,会跳转到登录界面