攔截器
概述
SpringMVC的處理器攔截器類似于Servlet開發中的過濾器Filter,用于對處理器進行預處理和后處理。開發者可以自己定義一些攔截器來實現特定的功能。
過濾器與攔截器的區別:攔截器是AOP思想的具體應用。
過濾器
-
servlet規范中的一部分,任何java web工程都可以使用
-
在url-pattern中配置了/*之后,可以對所有要訪問的資源進行攔截
攔截器
-
攔截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
-
攔截器只會攔截訪問的控制器方法, 如果訪問的是jsp/html/css/image/js是不會進行攔截的(自帶靜態資源過濾)
structs2也有攔截器,他們之間的區別:
-
從攔截級別上看,springMVC是方法級別的攔截,而structs2是類級別的攔截
-
數據獨立性:springMVC方法間獨立,獨享request和response
所以struct2的配置文件要大于spring MVC
自定義攔截器
那如何實現攔截器呢?
想要自定義攔截器,必須實現 HandlerInterceptor 接口。
1、新建一個Moudule , springmvc-07-Interceptor , 添加web支持,和我前幾期博客配置一致
2、配置web.xml 和 applicationContext.xml 文件
3、編寫一個攔截器
?
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("================處理后===============");}?@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("================清理===============");}}
在springmvc的配置文件中配置攔截器
?
<!-- ? 攔截器配置--><mvc:interceptors><mvc:interceptor><!-- ? ? ? ? ? 包括這個請求下面的所有的請求--><mvc:mapping path="/**"/><bean class="com.lyc.Interceptor.MyInterceptor"/></mvc:interceptor></mvc:interceptors>
編寫一個Controller,接收請求
package com.lyc.controller;?import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;?@RestControllerpublic class InterceptorController {@GetMapping("/h1")public String test(){System.out.println("這個Controller執行了");return "ok";}}
當返回值為true時
當返回值為false時
Controller請求被攔截了,無法發送到前端
實現需要先登錄才可以進入首頁
案例代碼展示
先編寫前端頁面
首頁:
?<%@ 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>
登陸頁面:
<%@ 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
?<%@ 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>
在編寫攔截器時,思考,要求沒有登陸時點擊首頁會跳到登陸頁面,登陸后跳轉到首頁,再刷新也可以進首頁,注銷后需要再進入登陸頁面
由此得出
LoginInterceptor.javapackage 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 {@Overridepublic 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
? <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
?
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頁面
以上就是攔截器的簡單應用,希望對大家有所幫助!!!