SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-expressionartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>2.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.5version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.5version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.5version>
dependency>
dependencies>
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>CharacterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>CharacterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilterfilter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>HttpPutFormContentFilterfilter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilterfilter-class>
filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<welcome-file-list>
<welcome-file>/views/index.jspwelcome-file>
welcome-file-list>
web-app>
springmvc.xml
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.newcapec"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-handler/>
beans>
DemoController.java
@Controller
@RequestMapping("/demo")
public class DemoController {
@RequestMapping("/find")
public String find(){
System.out.println("DemoController的find方法...");
return "success";
}
@RequestMapping("/add")
public String add(){
System.out.println("DemoController的add方法...");
return "success";
}
@RequestMapping("/edit")
public String edit(){
System.out.println("DemoController的edit方法...");
return "success";
}
@RequestMapping("/remove")
public String remove(){
System.out.println("DemoController的remove方法...");
return "success";
}
}
EmpController.java
@Controller
@RequestMapping("/emp")
public class EmpController {
@RequestMapping("/find")
public String find(){
System.out.println("EmpController的find方法...");
return "success";
}
@RequestMapping("/add")
public String add(){
System.out.println("EmpController的add方法...");
return "success";
}
@RequestMapping("/edit")
public String edit(){
System.out.println("EmpController的edit方法...");
return "success";
}
@RequestMapping("/remove")
public String remove(){
System.out.println("EmpController的remove方法...");
return "success";
}
}
实现HandlerInterceptor接口,并且实现其中三个抽象方法
/**
* springmvc中的拦截器对象
* 1.编写代码:实现拦截器接口 HandlerInterceptor
* 2.配置拦截器
*/
public class Demo1Interceptor implements HandlerInterceptor {
/**
* preHandle方法,预处理
* 作用:在请求进入指定Controller方法之前,执行的方法(对请求进行验证)
* @param request 请求对象
* @param response 响应对象
* @param handler 请求将要执行的Controller对象
* @return 布尔类型:true表示请求放行,继续向后执行(有可能进入下一个拦截器,也有可能进入Controller)
* false表示拦截请求,请求不能继续向后执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Demo1Interceptor拦截器中的preHandle方法执行了...");
return true;
}
/**
* postHandle 后处理
* @param request 请求对象
* @param response 响应对象
* @param handler 正在执行的Controller对象
* @param modelAndView 模型和视图数据,Controller方法执行完成之后的返回值
*
* 注意:此方法必须在请求进入Controller之后才会执行,如果没有进入Controller是不会执行的
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Demo1Interceptor拦截器中的postHandle方法执行了...");
}
/**
* afterCompletion 请求处理完成之后
* @param request 请求对象
* @param response 响应对象
* @param handler 已经执行过的Controller对象
* @param ex Controller方法抛出的异常对象
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("Demo1Interceptor拦截器中的afterCompletion方法执行了...");
}
}
方法解析:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.newcapec.interceptor.Demo1Interceptor"/>
mvc:interceptor>
mvc:interceptors>
/* 与 /**的区别:
请求路径 | 解析 |
---|---|
/find | 配置/*或/**可进入 |
/demo/find | 配置/**可进入 |
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Titletitle>
head>
<body>
<div style="text-align: center">
<h1>拦截器h1>
<h2>当前登录用户:${sessionScope.loginUser}h2>
<a href="demo/find">测试查询a><br>
<a href="demo/add">测试新增a><br>
<a href="demo/edit">测试编辑a><br>
<a href="demo/remove">测试删除a><br>
<a href="emp/find">员工查询a><br>
<a href="emp/add">员工新增a><br>
<a href="emp/edit">员工编辑a><br>
<a href="emp/remove">员工删除a><br>
<a href="auth/logout">退出系统a><br>
div>
body>
html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Titletitle>
head>
<body>
<div style="text-align: center">
<h1>操作成功h1>
div>
body>
html>
定义第二个拦截器Demo2Interceptor.java
public class Demo2Interceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("第二个拦截器中的preHandle方法执行了...");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("第二个拦截器中的postHandle方法执行了...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("第二个拦截器中的afterCompletion方法执行了...");
}
}
配置:
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.newcapec.interceptor.Demo2Interceptor"/>
mvc:interceptor>
每个拦截器的preHandler方法都返回true
Demo1Interceptor的preHandler方法返回true,Demo2Interceptor返回false
每个拦截器的preHandler方法都返回false
用户身份认证拦截器的实现
@Controller
@RequestMapping("/auth")
public class LoginController {
@RequestMapping("/login")
public String login(String username, String password, HttpSession session, Model model){
//模拟查询:根据用户名和密码查询数据
if("admin".equals(username) && "123".equals(password)) {
//比对成功,用户登录
//将用户信息放入session域对象
session.setAttribute("loginUser", username);
return "index";
}
model.addAttribute("message", "username or password is invalid");
return "login";
}
@RequestMapping("/logout")
public String logout(HttpSession session){
session.removeAttribute("loginUser");
session.invalidate();
return "login";
}
}
public class LoginInterceptor implements HandlerInterceptor {
/**
* 身份认证:
* 过滤器:
* 1.从session域中获取用户的登录信息
* 2.判断用户信息是否为空
* 3.不为空(表示已登录)放行(doFilter方法)
* 4.为空(表示未登录)
* 5.判断当前请求是否为登录请求或无需登录可执行请求(身份认证白名单)
* 6.如果为白名单请求,放行
* 7.如果不是,拦截,跳转login,信息提示...
*
* 拦截器:
* 1.从session域中获取用户的登录信息
* 2.判断用户信息是否为空
* 3.不为空(表示已登录)放行(返回true)
* 4.为空(表示未登录),拦截,跳转login,信息提示...
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("身份认证拦截器执行.....");
HttpSession session = request.getSession();
Object userInfo = session.getAttribute("loginUser");
if(userInfo == null){
request.setAttribute("message", "you are not login.");
request.getRequestDispatcher("/views/login.jsp").forward(request, response);
return false;
}
return true;
}
@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="/**"/>
<mvc:exclude-mapping path="/auth/login"/>
<bean class="com.newcapec.interceptor.LoginInterceptor"/>
mvc:interceptor>
mvc:interceptors>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Titletitle>
head>
<body>
<div style="text-align: center">
<h1>用户登录h1>
<div style="color: red;">${message}div>
<form action="auth/login" method="post">
<p>用户名:<input type="text" name="username">p>
<p>密 码:<input type="text" name="password">p>
<p><button>登录button>p>
form>
div>
body>
html>