SpringMVC拦截器应用案例

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC拦截器应用案例相关的知识,希望对你有一定的参考价值。

SpringMVC拦截器应用案例

本节通过拦截器来完成一个用户登录权限的web应用,具体要求如下:只有成功登录的用户才能访问系统的主页面main.jsp,如果没有成功登录而直接访问主页面,则拦截器请求拦截,并转发到登录页面login.jsp,等成功登录的用户在系统主页单击推出按钮,则回到登录页面。
1-在IDEA中创建web应用ch13-2,在WEB-INF目录创建目录lib,在lib目录中导入SpringMVC相关jar包,并将lib添加为项目库。

2-在inedx.xml中配置DispatcherSevlet,同时需要配置 CharacterEncodingFilter解决中文乱码问题

<?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"
         id = "WebApp_ID" version="4.0">
    <!--部署DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <!--表示容器启动时加载的servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--任意的请求都通过DispatcherServlet-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置 CharacterEncodingFilter解决中文乱码问题-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <!-- 配置编码格式为UTF-8 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

3-在src目录下创建pojo包,在该包中创建User类,将用户名和密码封装到该类中。

public class User {
    private String uname ;
    private String upwd ;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUpwd() {
        return upwd;
    }

    public void setUpwd(String upwd) {
        this.upwd = upwd;
    }
}

4-在src目录下创建包contoller,在该包中创建控制器类UserController,具体代码如下:

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

import javax.servlet.http.HttpSession;
@Controller
public class UserController {
    //登录页面初始化
    @RequestMapping("/toLogin")
    public String initLogin(){
        return "login" ;
    }
    //处理登录功能
    @RequestMapping("/login")
    public String login(User user, Model model, HttpSession session){
        System.out.println(user.getUname()) ;
        if("wang".equals(user.getUname()) && "123456".equals(user.getUpwd())){
            //登录成功,将用户信息保存到session对象
            session.setAttribute("user", user) ;
            //重定向到主页的跳转方法
            return "redirect:main" ;
        }
        model.addAttribute("msg", "用户名或者密码错误,请重新登录") ;
        return "login" ;
    }
    //跳转到主页面
    @RequestMapping("/main")
    public String toMain(){
        return "main" ;
    }
    //退出登录
    @RequestMapping("/logout")
    public String logOut(HttpSession session){
        //清除session
        session.invalidate();
        return "login" ;
    }
}

5-在src目录下创建interceptor包,在该包中创建拦截器类LoginInterceptor,在控制器处理之前进行拦截。

import org.springframework.web.servlet.HandlerInterceptor;
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 handler) throws Exception {
        //获取请求的url
        String url = request.getRequestURI() ;
        //login.jsp或者登录的时候请求放行,不拦截
        if(url.indexOf("/toLogin") >= 0 || url.indexOf("/login") >= 0){
            return true ;
        }
        //获取session
        HttpSession session = request.getSession() ;
        Object obj = session.getAttribute("user") ;
        if(obj != null){
            return true ;
        }
        //没有登录且不是登录页面,则转发到登录页面,并给出错误提示信息
        request.setAttribute("msg", "还没登录,请先登录");
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
        return false;
    }
}

6-配置WEB-INF目录下创建SpringMVC配置文件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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--使用扫描机制,扫描控制器类-->
    <context:component-scan base-package="controller"/>
    <mvc:annotation-driven />
    <!--annotation-driven用于简化开发的配置,注解DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter-->
    <!--使用resources过滤掉不需要dispatcherservlet的资源,例如静态资源,在使用resources时必须使用annotation-driven,否则resources会阻止任意控制器被调用-->

    <!--配置视图解析器-->
    <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" id = "internalResourceViewResolver">
        <!--前缀-->
        <property name = "prefix" value = "/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name = "suffix" value = ".jsp"/>
    </bean>
    <mvc:interceptors>
        <!--配置拦截器的作用路径为任意路径-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class = "interceptor.Interceptor1"/>
        </mvc:interceptor>

        <mvc:interceptor>
            <mvc:mapping path="/gotoTest"/>
            <bean class = "interceptor.Interceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

7-创建视图JSP页面,在WEB-INF目录下创建login.jsp和main.jsp两个视图文件。

login.jsp:

<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/8/10
  Time: 21:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
<form : action = "${pageContext.request.contextPath}/login" method = "post">
    用户名:<input type = "text" name = "uname" /> <br>
    密码  :<input type = "password" name = "upwd"/> <br>
    <input type = "submit" value = "登录"/>
</form>
</body>
</html>

main.jsp:

<%--@elvariable id="user" type="pojo.User"--%>
<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/8/10
  Time: 21:34
  To 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.uname}<br>
<a href = "${pageContext.request.contextPath}/logout">退出</a>
</body>
</html>

8-发布并测试应用,将应用发布到Tomcat,并启动tomcat,然后首先直接访问主页面网址:http://localhost:8080/ch13_2_war_exploded/main
,将被拦截器拦截,提示先登录,并跳转到对应的登录页面。

输入正确的用户名和密码后,点击登录,如下所示:

点击退出按钮,如下所示:

输入错误的登录信息,效果如下:

1-在SpringMVC框架中如何自定义拦截器?如何配置自定义拦截器?
答:定义一个拦截器可以通过两种方式:一种是通过实现HandlerInterceptor接口或继承HandlerInterceptor接口的实现类来定义;另一种是通过实现WebRequestInterceptor接口或者继承WebRequestInterceptor接口的实现类。定义完拦截器需要进行配置,mvn:interceptors元素用于配置一组拦截器,其子元素bean配置一个全局拦截器,拦截所有请求,mvn:interceptor定义指定路径的拦截器,其子元素mvn:mapping用于配置拦截器作用的路径,该路径在其属性path中定义,path的属性值/**表示拦截所有路径,/goTest表示拦截以/goTest结尾的路径,如果请求路径中包含不需要拦截的内容,可以使用mvc:exclude-mapping子元素进行配置。
需要注意的是:mvn:interceptor元素的子元素必须按照mvc:mapping,mvc:exclude-mapping,bean的顺序进行配置。

2-请简述单个拦截器和多个拦截器的执行流程?
在配置文件中如果只定义一个拦截器,程序将首先首先执行拦截器中的preHandle方法,如果该方法返回为true,程序将执行控制控制器中的请求处理方法,然后执行postHandle方法,返回视图后执行afterCompletion方法。
在web应用中通常需要有多个拦截器同时工作,这时它们的preHandler()方法将按照配置文件中拦截器的配置顺序进行,而它们的postHandler方法和afterCompletion方法将按照配置顺序的反序执行。

以上是关于SpringMVC拦截器应用案例的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC 学习笔记 --- [SpringMVC的文件上传与拦截器,以及更新登录用户头像的简易案例]

SpringMVC 拦截器

springMVC

springMVC

springMVC

springMVC