一、SpringMVC 拦截器
SpringMVC 的拦截器类似于 Servlet 中的过滤器,用于对处理器进行预处理和后处理。我们可以用拦截器来实现一些特定的功能。
拦截器和过滤器的区别:拦截器是AOP思想的具体应用
过滤器
- servlet规范中的一部分,任何java web工程都可以使用
- 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器
- 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
- 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
下面让我们看一下如何实现拦截器。
二、实现拦截器
实现拦截器我们必须要实现 HandlerInterceptor 接口,根据返回值决定是否进行拦截(true 不拦截,false 进行拦截)
1、实现 HandlerInterceptor 接口
package com.lxc.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("-------处理前---------");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("---------处理后---------");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("-----------清理----------");
}
}
2、在 springmvc-servlet.xml 中配置SpringMVC 拦截器
<!--关于拦截器的配置-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.lxc.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
其中<mvc:mapping path="/**"/>代表着 该 路径下的所有子路径都进行拦截判断
/** 包括路径及其子路径
/user/* 拦截的是user下的子路径,而子路径的子路径就不会进行拦截
/admin/add/user不会被拦截--> <!--/admin/** 拦截的是/admin/下的所有-->
3、index.jsp 的编写
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<p>
<a href="${pageContext.request.contextPath}/interceptor">拦截器测试</a>
</p>
</body>
</html>
4、Controller 类的编写
package com.lxc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class InterceptorController {
@RequestMapping("/interceptor")
@ResponseBody
public String test() {
System.out.println("控制器方法执行了");
return "hello";
}
}
5、运行结果
三、案例之认证用户
当我们访问一些网站的私密的信息时,如查看一些题库,系统会自动跳转到登录页面,导致我们不能直接访问,这个原理就是拦截器对一些请求进行拦截,下面让我们用代码来实现一下这个案例
1、编写 Controller 类
package com.lxc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("user")
public class InterceptorController {
//跳转到登录页面
@RequestMapping("/toLogin")
public String toLogin() {
return "login";
}
// 登录页面
@RequestMapping("login")
public String login(String username, String pwd, HttpSession session) {
System.out.println("接收前端消息" + username);
session.setAttribute("user", username);
return "success";
}
// 注销
@RequestMapping("logout")
public String logout(HttpSession session) {
session.invalidate();
return "/login";
}
// 跳转到成功页面
@RequestMapping("/toSuccess")
public String toSuccess() {
return "success";
}
}
2、拦截器的编写
package com.lxc.interceptor;
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;
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
//如果是登录界面不拦截
if (request.getRequestURI().contains("login")) {
return true;
}
HttpSession session = request.getSession();
//如果 session 会话中有对象也不拦截
if (session.getAttribute("user") != null) {
return true;
}
//如果想要直接跳转到成功页面则进行拦截
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
3、配置文件
<!--关于拦截器的配置-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/**"/>
<bean class="com.lxc.interceptor.UserInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
4、前端(首页)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
background-color: black;
color: white;
width: 10%;
height: 50px;
font-size: 20px;
line-height: 50px;
margin: auto;
margin-top: 20px;
padding: auto;
text-align: center;
border-radius: 15px;
}
a:hover {
color: darkcyan;
}
a:link {
text-decoration: none;
}
a {
color: aliceblue;
}
body {
color: darkslateblue;
}
</style>
</head>
<body>
<div>
<a href="${pageContext.request.contextPath}/user/toLogin">登录</a>
</div>
<div>
<a href="${pageContext.request.contextPath}/user/toSuccess">成功页面</a>
</div>
</body>
</html>
5、前端(登录界面)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<hr>
<form method="post" action="${pageContext.request.contextPath}/user/login">
用户名:<input type="text" name="username"> <br>
密码: <input type="password" name="pwd"> <br>
<input type="submit" value="提交">
</form>
</body>
</html>
6、前端(成功界面)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>成功页面</title>
</head>
<body>
<h1>登录成功,admin为:${user}</h1>
<p>
<a href="${pageContext.request.contextPath}/user/logout">注销</a>
</p>
</body>
</html>
编写好之后就可以进行测试。