SpringMVC(11)——拦截器

概述

Spring MVC的拦截器(Interceptor)主要用于拦截用户的请求并做相应的处理,通常应用在全选验证,判断用户是否登录等功能上。

在SpringMVC框架中定义一个拦截器需要对拦截器进行定义和配署,定义一个拦截器可以通过两种方式:一种是通过实现HandlerInterceptor接口或继承HandlerInterceptor接口的实现类来定义;另一种是通过实现WebRequestInterceptor接口或继承WebRequestInterceptor接口的实现类来定义。

以实现HandlerInterceptor接口为例:

package springmvcdemo.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 TestInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        // preHandle方法在控制器的处理请求方法执行之前执行
        // 返回true表示继续向下执行,返回false表示中断后续操作
       return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        // postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        // afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行
    }
}

实现接口中的3个方法:

  • preHandle:preHandle方法在控制器的处理请求方法执行之前执行,返回true表示继续向下执行,返回false表示中断后续操作。
  • postHandle:postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行
  • afterCompletion:afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行

使用拦截器需要在springmvc的配置文件中进行配置

    <!--配置拦截器-->
    <!--<mvc:interceptor>元素的子元素必须按照如下的顺序进行配置-->
    <mvc:interceptors>
        <!--配置一个全局拦截器,拦截所有请求-->
        <!--子元素<bean>定义的是全局拦截器,即拦截所有请求-->
        <bean class="springmvcdemo.interceptor.TestInterceptor"/>
        <!--<mvc:interceptor>元素中定义的是指定路径的拦截器,其子元素<mvc:mapping>用于配置拦截器作用的路径,该路径在其属性path中定义-->
        <mvc:interceptor>
            <!--配置拦截器作用的路径-->
            <!--path的属性值为”/**“表示拦截所有路径-->
            <mvc:mapping path="/**" />
            <!--如果在请求路径中包含不需要拦截的内容,通过<mvc:exclude-mapping>子元素进行配置-->
            <mvc:exclude-mapping path=""/>
            <!--定义在<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截-->
            <bean class="springmvcdemo.interceptor.FirstInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--配置拦截器作用的路径-->
            <!--path的属性值为”/goto“表示拦截所有以”goto“结尾的路径-->
            <mvc:mapping path="/goto" />
            <!--如果在请求路径中包含不需要拦截的内容,通过<mvc:exclude-mapping>子元素进行配置-->
            <mvc:exclude-mapping path=""/>
            <!--定义在<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截-->
            <bean class="springmvcdemo.interceptor.FirstInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

实例

通过拦截器实现一个用户登录权限验证,只有成功登录的用户才能访问系统的主页面main.jsp,而没有成功登录而直接访问主页面将被拦截器拦截,并转发到登录页面login.jsp。当成功登录的用户在系统主页面单击“退出”超链接时回到登录页面。

创建springmvc项目并按下图创建文件及文件夹:

各文件的代码如下:

StudentController.java

package springmvcdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import springmvcdemo.pojo.Student;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/student")
public class StudentController {

    @RequestMapping("/initLogin")
    public String initLogin() {
        return "login";
    }

    @RequestMapping("/login")
    public String login(Student student, Model model, HttpSession session) {
        if ("hello".equals(student.getUsername()) && "world".equals(student.getPassword())) {
            // 登录成功将用户信息保存到session对象中
            session.setAttribute("student", student);
            //重定向到主页面的跳转方法
            return "redirect:/student/main";
        }
        model.addAttribute("errorMsg", "用户名或密码错误!");
        return "login";
    }

    /**
     * 跳转到主页面
     */
    @RequestMapping("/main")
    public String main() {
        // 跳转到main.jsp页面
        return "main";
    }

    /**
     * 退出登录
     */
    @RequestMapping("logout")
    public String logout(HttpSession session) {
        // 清除session
        session.invalidate();
        // 并跳转到登录页面
        return "login";
    }
}

LoginInterceptor.java

package springmvcdemo.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 {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        // 获取请求的URL
        StringBuffer url = request.getRequestURL();
        // login.jsp或登录请求放行,不进行拦截
        if (url.indexOf("/student/initLogin") >= 0 || url.indexOf("/student/login") >= 0) {
            return true;
        }
        // 获取session
        HttpSession session = request.getSession();
        Object student = session.getAttribute("student");
        // 如果用户已经登录则放行不进行拦截
        if (student != null) {
            return true;
        }
        // 没有登录且不是登录页面则转发到登录页面,并给出错误提示
        request.setAttribute("errorMsg", "还没登录,请先登录!");
        // 转发到login.jsp
        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 {

    }
}

Student.java

package springmvcdemo.pojo;

public class Student {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--使用扫描机制扫描控制器类,控制器类都在controller包及其子包下-->
    <context:component-scan base-package="springmvcdemo.controller"/>

    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--配置拦截器的路径-->
            <mvc:mapping path="/**"/>
            <bean class="springmvcdemo.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

    <!--配置视图解析器-->
    <!--配置视图解析器成功后,RegisterController和LoginController控制器类的视图路径仅需提供register和login,视图解析器将会自动添加前缀和后缀-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
    <%--显示错误提示信息--%>
    <span style="color: red">${errorMsg}</span>
    <form action="/student/login" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

main.jsp

<%@ page import="springmvcdemo.pojo.Student" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>主页</title>
</head>
<body>
    <%
        Student student = (Student)session.getAttribute("student");
    %>
    当前用户:<%=student.getUsername()%><br>
    <a href="/student/logout">退出</a>
</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <!--部署DispatcherServlet-->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--加载Spring MVC的配置文件,配置文件可以放在项目目录的任意位置,使用init-param元素加载配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--配置文件的位置-->
            <param-value>/WEB-INF/config/springmvc-config/springmvc-servlet.xml</param-value>
        </init-param>
        <!--表示容器在启动时立即加载servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <!--处理所有URL-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--避免中文乱码-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

index.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
    <h1>Hello World!</h1>
    <a href="/student/initLogin">登录</a>
</body>
</html>

运行效果如下:

点击【登录】超链接跳转到login.jsp页面。

在地址栏输入地址:http://localhost:8080/student/main

由于登录拦截器的拦截,没有登录的用户只能被拦截然后转发到login.jsp。

登录成功的用户为:【用户名:hello;密码:world】

点击【登录】按钮,访问main.jsp页面成功

点击【退出】超链接退出登录,再次转发到login.jsp

 

如果对完整源码有兴趣。

可搜索微信公众号【Java实例程序】或者扫描下方二维码关注公众号获取更多。

注意:在公众号后台回复【CSDN201911161424】可获取本节源码。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值