springMVC-拦截器详解

拦截器

概述

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。

过滤器与拦截器的区别: 拦截器是AOP思想的具体应用。

过滤器

  • servlet规范中的一部分,任何java web工程都可以使用

  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用

  • 拦截器只会拦截访问的控制器方法 , 如果访问的是jsp/html/css/image/js是不会进行拦截的(自带静态资源过滤)

structs2也有拦截器,他们之间的区别:

  1. 从拦截级别上看,springMVC是方法级别的拦截,而structs2是类级别的拦截

  2. 数据独立性:springMVC方法间独立,独享request和response

所以struct2的配置文件要大于spring MVC

自定义拦截器

那如何实现拦截器呢?

想要自定义拦截器,必须实现 HandlerInterceptor 接口。

1、新建一个Moudule , springmvc-07-Interceptor , 添加web支持,和我前几期博客配置一致

2、配置web.xml 和 applicationContext.xml 文件

3、编写一个拦截器

复制代码
 
java 复制代码
package com.lyc.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 {
     @Override
     //return true表示放行,执行下一个拦截器,false表示拦截
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         System.out.println("================处理前===============");
        return true;
     }
 ​
     @Override
     //日志
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         System.out.println("================处理后===============");
     }
 ​
     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
         System.out.println("================清理===============");
     }
 }

在springmvc的配置文件中配置拦截器

复制代码
 
XML 复制代码
<!--    拦截器配置-->
     <mvc:interceptors>
         <mvc:interceptor>
 <!--            包括这个请求下面的所有的请求-->
             <mvc:mapping path="/**"/>
             <bean class="com.lyc.Interceptor.MyInterceptor"/>
         </mvc:interceptor>
     </mvc:interceptors>

编写一个Controller,接收请求

java 复制代码
package com.lyc.controller;
 ​
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RestController;
 ​
 @RestController
 public class InterceptorController {
     @GetMapping("/h1")
     public String test(){
         System.out.println("这个Controller执行了");
         return "ok";
     }
 }

当返回值为true时

当返回值为false时

Controller请求被拦截了,无法发送到前端

实现需要先登录才可以进入首页

案例代码展示

先编写前端页面

首页:

html 复制代码
 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head>
     <title>Title</title>
 </head>
 <body>
 <h1>首页</h1>
 <span>${username}</span>
 <p>
     <a href="${pageContext.request.contextPath}/user/goOut">注销</a>
 </p>
 </body>
 </html>

登陆页面:

html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head>
     <title>Title</title>
 </head>
 <body>
 <%--在WEB-INF下的所有页面或者资源,只能通过controller,或者servlet进行访问--%>
 <h1>登陆页面</h1>
 <form action="${pageContext.request.contextPath}/user/login" method="post">
     用户名:<input type="text" name="username" required>
     密码:<input type="password" name="password" required>
     <input type="submit" value="登陆">
 </form>
 </body>
 </html>

index.jsp

html 复制代码
 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head>
     <title>Title</title>
 </head>
 <body>
 <h1><a href="${pageContext.request.contextPath}/user/goLogin">登陆页面</a></h1>
 <h1><a href="${pageContext.request.contextPath}/user/main">首页</a></h1>
 </body>
 </html>

在编写拦截器时,思考,要求没有登陆时点击首页会跳到登陆页面,登陆后跳转到首页,再刷新也可以进首页,注销后需要再进入登陆页面

由此得出

java 复制代码
LoginInterceptor.java

 package com.lyc.Interceptor;
 ​
 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 {
         HttpSession session = request.getSession();
         //在登陆页面上也需要放行
         if (request.getRequestURI().contains("goLogin")){
             return true;
         }
              // 判断用户是否登录
         //第一次登陆,也是没有session的
         if (request.getRequestURI().contains("login")){
             return true;
         }
         
         if (session.getAttribute("loginInfo")!= null){
             return true;
         }
        // 重定向到登录页面
         response.sendRedirect("http://localhost:8023/springmvc_07_intercepter_Web_exploded/user/goLogin");
         return false;
     }
 }

不要忘记在配置文件中注册拦截器的bean

XML 复制代码
  <mvc:interceptors>
         <mvc:interceptor>
 <!--            包括这个请求下面的所有的请求-->
             <mvc:mapping path="/**"/>
             <bean class="com.lyc.Interceptor.MyInterceptor"/>
         </mvc:interceptor>
         <mvc:interceptor>
             <mvc:mapping path="/user/**"/>
             <bean class="com.lyc.Interceptor.LoginInterceptor"/>
         </mvc:interceptor>
     </mvc:interceptors>

最后写Controller类

LoginController.java

复制代码
 
java 复制代码
package com.lyc.controller;
 ​
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.RequestMapping;
 ​
 import javax.servlet.http.HttpSession;
 ​
 @Controller
 @RequestMapping("/user")
 public class LoginController {
     @RequestMapping("/goLogin")
     public String login(){
         return "login";
     }
     @RequestMapping("/login")
     public String login(HttpSession session, String username, String password, Model model){
         //把用户的信息存在session中
         System.out.println("username===>"+username+"password===>"+password);
         session.setAttribute("loginInfo",username);
         model.addAttribute("username",username);
         return "main";
     }
     @RequestMapping("/main")
         public String main1(){
             return "main";
         }
         @RequestMapping("/goOut")
         public String goOut(HttpSession session){
             session.removeAttribute("loginInfo");
             return "main";
         }
 }

效果展示:

先进入

点击首页:

填写信息,点击登录按钮:

再次回到index.jsp:

再次点击首页,这次直接进入

点击注销方法

需要点击两次注销方法

第一次点击注销方法,先过的拦截器,还存在session,过了拦截器,再注销session,到达了main.jsp

第二次点击注销方法:session在第一次点击已经移除,方法被拦截,返回login页面

以上就是拦截器的简单应用,希望对大家有所帮助!!!

相关推荐
喜欢吃豆9 分钟前
prompts提示词经典模板
java·服务器·数据库·人工智能·prompt
盖世英雄酱5813614 分钟前
事务消息用在用么场景?如何使用
java·架构
无名之逆17 分钟前
高性能文件上传服务
java·服务器·网络·http·rust
Aska_Lv22 分钟前
业务架构设计---MQ出现消息乱序了如何解决
后端
Ray-国38 分钟前
2025蓝桥杯JavaB组
java·职场和发展·蓝桥杯
用户8726182459071 小时前
JUnit 5的框架介绍
后端
KEEPMA1 小时前
在线上定位1G日志文件中的异常信息时,我这样做合适吗
java·服务器·数据库
一只小闪闪1 小时前
langchain4j搭建失物招领系统(六)---实现失物查询功能-RAG使用
java·人工智能·后端
uhakadotcom1 小时前
大数据处理与消息服务:Kafka、MNS和PySpark的区别与应用
后端·面试·github
夜宵饽饽1 小时前
传输层-MCP的搭建(一)
javascript·后端