8、拦截器
8.1 认识拦截器
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
过滤器与拦截器的区别:拦截器是AOP思想的具体应用。
过滤器
- servlet规范中的一部分,任何java web工程都可以使用
- 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器
-
拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
-
拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
8.2 自定义拦截器
如何实现拦截器呢?
想要自定义拦截,必须实现HandleInterceptor接口
1、新建一个Moudule , springmvc-07-Interceptor , 添加web支持
2、配置web.xml 和 springmvc-servlet.xml 文件
3、编写一个拦截器
我们主要重写三个方法 最主要的是 第一个方法的返回值是true还是false
package com.yhn.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 {
// 在请求处理的方法之前执行
// return true 代表执行下一个拦截器 (放行)
// return false 代表不执行下一个拦截器 (不放行)
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("===处理前===");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("===处理后===");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("===清理===");
}
}
我们写完拦截器之后 现在还没有拦截功能 我们要去Spring去注册它
4、在springmvc的配置文件中配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置拦截器路径 /** 为包括路径及子路径-->
<!-- /admin/* 代表拦截的是/admin/add 但不会拦截 /admin/add/user 这种路径-->
<!-- /admin/** 代表拦截的是/admin/ 下的所有请求-->
<mvc:mapping path="/**"/>
<!--配置拦截器bean-->
<bean class="com.yhn.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
5、我们去写一个Controller 去接受请求
package com.yhn.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class InterceptorController {
@RequestMapping("/t1")
public String testFunction(){
System.out.println("控制器的方法执行了");
return "ok";
}
}
6、启动Tomcat 测试一下 注意: 这里项目中要有WEB-INF要有lib目录 需手动添加
测试结果:
因为第一个方法 返回True 所以可以执行Controller中的方法
如果是false 打印只有 处理前 这一句话
8.3 验证用户是否登录 (认证用户)
实现思路:
1、有一个登陆页面,需要写一个controller访问该页面。
2、登陆页面有一提交表单的动作。需要在controller中处理。判断用户名密码是否正确。如果正确,向session中写入用户信息。返回登陆成功。
3、拦截用户请求,判断用户是否登陆。如果用户已经登陆。放行, 如果用户未登陆,跳转到登陆页面
测试:
1、编写一个登录页面 login.jsp 提交表单
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登陆页面</h1>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名:<input type="text" name="username">
<br>
密码:<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
2、编写一个Controller处理请求
package com.yhn.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
// 这里要用视图解析器 不能用RestController
@Controller
@RequestMapping("/user")
public class UserController {
// 两个跳转页面
@RequestMapping("/jumpLogin")
public String jumpLogin(){
return "login";
}
@RequestMapping("/jumpSuccess")
public String jumpSuccess(){
return "success";
}
// 登录
@RequestMapping("/login")
public String login(HttpSession session,String username, String password){
System.out.println("接收到了前端的" + username);
// 将用户信息存入Session 拦截器要进行判断
session.setAttribute("username",username);
// 跳转到成功页面
return "success";
}
// 注销
@RequestMapping("/logout")
public String logout(HttpSession session){
// 移除 Session属性
session.removeAttribute("username");
return "login";
}
}
3、编写一个登录成功后的成功页面 success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>成功页面</h1>
${username}
<a href="${pageContext.request.contextPath}/user/logout">注销</a>
</body>
</html>
4、在index页面上测试跳转!启动Tomcat测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>首页</h1>
<a href="${pageContext.request.contextPath}/user/jumpLogin">登陆</a>
<a href="${pageContext.request.contextPath}/user/jumpSuccess">成功页</a>
</body>
</html>
5、编写用户登录拦截器 这里还要在Spring配置拦截器
所有的请求都会先走拦截器
package com.yhn.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 LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果是登录页面请求 放行
if (request.getRequestURI().contains("login")){
return true;
}
// 如果Session中有username 放行
HttpSession session = request.getSession();
if (session.getAttribute("username")!=null){
return true;
}
// 到这一步 说明没有登录 则跳转到登录页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
6、在SpringMVC的配置文件中配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置拦截器路径 /** 为包括路径及子路径-->
<!-- /admin/* 代表拦截的是/admin/add 但不会拦截 /admin/add/user 这种路径-->
<!-- /admin/** 代表拦截的是/admin/ 下的所有请求-->
<mvc:mapping path="/**"/>
<!--配置拦截器bean-->
<bean class="com.yhn.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
7、重启Tomcat 测试
OK!测试登录拦截功能有效! 可以验证用户Session是否存在