SpringMVC拦截器
1.什么是拦截器
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
**过滤器与拦截器的区别:**拦截器是AOP思想的具体应用。
过滤器
- servlet规范中的一部分,任何java web工程都可以使用
- 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器
- 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
- 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
2.如何实现拦截器
想要自定义拦截器,必须实现 HandlerInterceptor 接口
在web项目中
1、配置web.xml 和 springmvc-servlet.xml 文件
2、编写一个拦截器
- 编写MyInterceptor类
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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("=============处理前=============");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("=============处理后=============");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("=============清理=============");}
}
- 在springmvc的xml文件中配置拦截器
<!-- 拦截器--><mvc:interceptors><mvc:interceptor><!--/** 包括路径及其子路径--><!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截--><!--/admin/** 拦截的是/admin/下的所有--><mvc:mapping path="/**"/><bean class="com.sangyu.config.MyInterceptor"/></mvc:interceptor></mvc:interceptors>
- 编写一个controller,接受请求
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";}
}
- 前端index.jsp页面
- 启动Tomcat测试
3.拦截器实现判断用户是否登录
- 编写index.jsp默认界面
<%--Created by IntelliJ IDEA.User: 19401Date: 2023/3/10Time: 16:20To 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: 19401Date: 2023/3/10Time: 17:23To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</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: 19401Date: 2023/3/10Time: 17:23To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
${user}
<a href="${pageContext.request.contextPath}/logout">注销</a>
</body>
</html>
- 编写对应请求的controller
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";}}
- 运行Tomcat,发现在首页点击登录,能够跳转到login.jsp页面,输入信息后额能进入success.jsp页面,也携带有信息,说明请求处理成功
但是我们发现一个问题,在index.jsp页面中,我们不点击登录,直接点击首页,也能够跳转到success.jsp页面,这是很不合理的,所以我们需要加上拦截器来判断登录状态
- 编写拦截器LoginInterceptor
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 {@Overridepublic 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;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}
- 在springmvc的xml文件中注册拦截器
<!-- 拦截器--><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.sangyu.config.LoginInterceptor"/></mvc:interceptor></mvc:interceptors>
此时,我们在index.jsp页面点击首页,就不会直接进入success.jsp页面,会跳转到登录界面