天天看點

SpringMVC之攔截器一、攔截器概述二、攔截器的執行流程三、應用案列——使用者登入權限驗證四、攔截器小結

文章目錄

  • 一、攔截器概述
    • (一)攔截器的實作方式
    • (二) 攔截器的配置
  • 二、攔截器的執行流程
    • (一)單個攔截器的執行流程
    • (二)多個攔截器的執行流程
  • 三、應用案列——使用者登入權限驗證
  • 四、攔截器小結

一、攔截器概述

SpringMVC的攔截器(Interceptor)與java Servlet的過濾器(Filter)類似,用于攔截使用者的請求并且做出相應的處理。一般應用于權限認證、記錄請求資訊的日志、判斷使用者是否登陸等功能。

(一)攔截器的實作方式

一種是通過實作 Handlerlnterceptor 接口; 另一種是通過實作 WebRequestlnterceptor 接口。
           

以實作 Handlerlnterceptor 接口的定義方式為例,自定義攔截器類的代碼如下所示。

public class TestInterceptor implements HandlerInterceptor{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("preHandle方法在控制器處理請求方法前執行");
		/**
		 * 傳回值為true表示繼續向下執行,false表示中斷後續操作
		 */
		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 方法在視圖渲染結束之後執行,即最後執行");
	}
}
           

• preHandler方法:該方法會在控制器方法前執行,其傳回值表示是否中斷後續操作。

• postHandle方法:該方法會在控制器方法調用之後,且解析視圖之前執行。 可以通過此 方法對請求域中的模型和視圖做出進一步的修改。

• afterCompletion方法:方法會在整個請求完成,即視圖渲染結束之後執行。 可以通過此方法實作一些資源清理、記錄曰志資訊等工作。

(二) 攔截器的配置

要使自定義的攔截器類生效,還需要在 Spring MVC 的配置檔案中進行配置。配置代碼如下:

<!-- 配置攔截器 -->
	<mvc:interceptors>
		<!-- 配置一個全局攔截器,攔截所有的請求 -->
		<bean class="interceptor.LoginInterceptor"></bean>
		<mvc:interceptor>
			<!-- 配置攔截器的作用路徑 -->
			<mvc:mapping path="/**"/>
			<!-- 配置不需要攔截的路徑 -->
			<mvc:exclude-mapping path=""/>
			<!-- 定義在<mvc:interceptor>下面的,表示對比對路徑的請求才進行攔截 -->
			<bean class="interceptor.LoginInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>
           

注意:

1、攔截器bean類所放的位置決定攔截器是全局攔截器還是局部攔截器

2、<mvc:mapping path="/gotoTest"/>表示攔截以/gotoTest結尾的路徑

3、 mvc:interceptor 中的子元素必須嚴格按照 <:mvc:mapping … />、<mvc:exclude-mapping … />、<bean … />的順序。

二、攔截器的執行流程

(一)單個攔截器的執行流程

1、控制器類InterceptorController

@Controller
public class InterceptorController {
	@RequestMapping("/gotoTest")
	public String gotoTest() {
		System.out.println("Controller正在測試攔截器,執行控制器的處理請求方法!");
		return "test";
	}
}
           

2、攔截器類

public class TestInterceptor implements HandlerInterceptor{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("preHandle方法在控制器處理請求方法前執行");
		/**
		 * 傳回值為true表示繼續向下執行,false表示中斷後續操作
		 */
		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 方法在視圖渲染結束之後執行,即最後執行");
	}
}

           

3、Springmvc-servlet.xml

<!-- 使用掃描機制掃描控制器類 -->
	<context:component-scan base-package="com.controller"></context:component-scan>
	<!-- 配置視圖解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
			id="internalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	<!-- 配置攔截器 -->
	<mvc:interceptors>
		<!-- 配置一個全局攔截器,攔截所有的請求 -->
		<bean class="interceptor.LoginInterceptor"></bean>
	</mvc:interceptors>
           

4、運作結果

SpringMVC之攔截器一、攔截器概述二、攔截器的執行流程三、應用案列——使用者登入權限驗證四、攔截器小結

(二)多個攔截器的執行流程

1、控制器和攔截器上同

2、Springmvc-servlet.xml檔案的配置

<mvc:interceptors>
		<mvc:interceptor>
			<!-- 配置攔截器的作用路徑 -->
			<mvc:mapping path="/**"/>
			<!-- 定義在<mvc:interceptor>下面的,表示對比對路徑的請求才進行攔截 -->
			<bean class="interceptor.Interceptor1"></bean>
		</mvc:interceptor>
		<mvc:interceptor>
			<!-- 配置攔截器的作用路徑 -->
			<mvc:mapping path="/gotoTest"/>
			<bean class="interceptor.Interceptor2"></bean>
		</mvc:interceptor>
	</mvc:interceptors>
           

3、運作結果

SpringMVC之攔截器一、攔截器概述二、攔截器的執行流程三、應用案列——使用者登入權限驗證四、攔截器小結
多個攔截器在執行的過程中,preHandle方法按照配置檔案中攔截器的配置順序執行,而postHandle和afterCompletion方法則按照配置檔案的反序執行。

三、應用案列——使用者登入權限驗證

1、建立POJO類

public class User {
	private String uname;
	private String upwd;
	//省略getter和setter方法
}
           

2、建立控制器類

@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("juhaijun".equals(user.getUname())
				&&"123456".equals(user.getUpwd())) {
			
			session.setAttribute("user", user);
			return "redirect:main";
		}
		model.addAttribute("msg", "使用者名或密碼錯誤");
		System.out.println("使用者名或密碼錯誤!");
		return "login";
	}
	/**
	 * 跳轉到首頁面
	 */
	@RequestMapping("/main")
	public String toMain() {
		return "main";
	}
	/**
	 * 登出
	 */
	@RequestMapping("/logout")
	public String logout(HttpSession session) {
//		清除session
		session.invalidate();
		return "login";
	}
}
           

3、建立攔截器類

public class LoginInterceptor implements HandlerInterceptor{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
//		擷取登陸的url
		String url= request.getRequestURI();
		System.out.println("請求路徑為:"+url);
//		登入界面不進行攔截
		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/views/login.jsp").forward(request, response);
		return false;
	}
}
           

4、建立jsp頁面——登入頁面和主界面

<body>
	${msg }
	<form action="${pageContext.request.contextPath }/login" method="post">
		
		使用者名:<input type="text" name="uname"/>
		密碼:<input type="password" name="upwd"/>
		<input type="submit" value="登入"/>
	</form>
</body>
           
<body>
	目前使用者:${user.uname }<br>
	<a href="${pageContext.request.contextPath }/logout">退出</a>
</body>
           

5、運作結果

SpringMVC之攔截器一、攔截器概述二、攔截器的執行流程三、應用案列——使用者登入權限驗證四、攔截器小結
SpringMVC之攔截器一、攔截器概述二、攔截器的執行流程三、應用案列——使用者登入權限驗證四、攔截器小結
SpringMVC之攔截器一、攔截器概述二、攔截器的執行流程三、應用案列——使用者登入權限驗證四、攔截器小結

四、攔截器小結

我們應當熟悉攔截器在單個執行和多個執行流程下的差別,着重掌握Springmvc配置檔案的配置流程。深入了解攔截器在上述應用案列中的作用。如有不足,多謝各位斧正。