天天看點

Spring MVC攔截器

Spring MVC攔截器的使用

Spring MVC中攔截器(Interceptor)是比較重要的功能,主要作用是攔截使用者的請求并根據實際需求以做出相應的處理。一般常用來使用者權限驗證、若需要同一賬号隻能登入一次還可以做是否已經登入判斷等。Struts2也有類似攔截器,而在Servlet中主要通過過濾器實作。

Spring MVC中攔截器是通過實作HandlerInterceptor接口完成的。要想使用攔截器,可以直接實作該接口,或者繼承實作了該接口的抽象類HandlerInterceptorAdapter。

以下以使用者權限驗證為例:

1.登入頁面loginUI.jsp

輸入使用者名、密碼,送出給背景處理,若使用者名、密碼錯誤時提示資訊通過message顯示。

<h1>${requestScope.message}</h1>
<form id="loginForm" action="${pageContext.request.contextPath}/user/login.do" method="post">
	<table>
		<tr>
			<td>使用者名</td>
			<td><input type="text" name="username"></td>
		</tr>
		<tr>
			<td>密碼</td>
			<td><input type="password" name="pwd"></td>
		</tr>
		<tr>
			<td colspan="2">
				<input type="submit" value="登入">
			</td>
		</tr>
	</table>
</form>
           

2.處理登入請求UserController.java

登入頁面在WEB-INF/jsp/user目錄下,是以需通過控制器轉發;登入頁面點選登入,判斷使用者名、密碼是否正确,正确則session中存儲登入使用者;否則傳回到登入頁面,給出提示資訊。

@Controller
@RequestMapping("/user")
public class UserController {

	/**
	* 使用者登入頁面
	*/
	@RequestMapping("/loginUI")
	public String loginUI() throws Exception {
		return "user/loginUI";
	}

	/**
	* 使用者登入
	*/
	@RequestMapping("/login")
	public String login(Model model, HttpSession session, User user) throws Exception {
		if (user != null && StringUtils.isNotBlank(user.getUsername()) && StringUtils.isNotBlank(user.getPwd())) {
			// 模拟使用者登入
			if (user.getUsername().equals("user") && user.getPwd().equals("user")) {
				// 登入成功,session域中存儲登入使用者
				session.setAttribute("user", user);

				model.addAttribute("message", "登入成功");
				return "success";
			}
		}
		model.addAttribute("message", "使用者或密碼錯誤");
		return "user/loginUI";
	}
}
           

3.攔截器RequestInterceptor.java

攔截所有以".do"字尾結尾的請求,對于請求登入頁面,首頁等頁面時放行;其他頁面時則需判斷使用者是否已經登入,即session中是否有使用者資訊,已登入則放行,否則跳轉進入登入頁面。

/**
 * 請求攔截器
 */
public class RequestInterceptor implements HandlerInterceptor {
	private static final String[] IGNORE_URI = { "/loginUI", "/login", "/index" };

	/**
	 * 請求攔截
	 * @param request
	 * @param response
	 * @param handler
	 * @return true:執行下一攔截器或Controller;false:請求結束
	 * <p>
	 *  1.preHandle方法是攔截器攔截到請求後最先執行的,是以可以在該方法中進行一些初始化或者攔截操作,如權限過濾。<br>
	 *  2.Spring MVC是鍊式調用,即可以存在多個攔截器進行攔截,隻有在preHandle傳回true時,才會繼續執行下一個攔截器或者Controller;<br>
	 * </p>
	 * */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		boolean result = false;

		String uri = request.getRequestURI();
		for (String u : IGNORE_URI) {
			if (uri.contains(u)) {
				result = true;
				break;
			}
		}

		if (!result) {
			User user = (User) request.getSession().getAttribute("user");
			if (user == null) {
				request.setAttribute("message", "請先登入再通路該頁面");
				request.getRequestDispatcher("/user/loginUI.do").forward(request, response);
			} else {
				result = true;
			}
		}

		return result;
	}
	
	/**
	 * <p>
	 * 	1.afterCompletion和postHandle在preHandle方法傳回值為true時才能執行;<br>
	 *  2.也就是在Controller方法執行後、視圖渲染之前調用,是以可以對Contoller處理後的ModelAndView對象進行操作;<br>
	 *  3.postHandle方法的執行次序和preHandle相反,類似于Struts2中的攔截器。<br>
	 * </p>
	 * */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv)
			throws Exception {
	}
	
	/**
	 * <p>
	 * 	1.afterCompletion和postHandle在preHandle方法傳回值為true時才能執行;<br>
	 *  2.該方法在整個請求結束之後,即視圖渲染結束後執行;<br>
	 *  3.該方法主要作用是進行資源的清理。<br>
	 * </p>
	 * */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e)
			throws Exception {
	}
}
           

4.攔截器配置

在springmvc.xml中通過<mvc:interceptors>配置攔截器,<mvc:interceptor>配置具體攔截器資訊,攔截的url,調用的攔截器類,可以配置多個攔截器,注意次序即可。

<!-- 定義攔截器 -->
<!-- path屬性
	/**:所有檔案夾及其子檔案夾 
	/* :所有檔案夾,不含子檔案夾
	/  :web項目的根目錄 
-->
<mvc:interceptors>
	<mvc:interceptor>
		<!-- <mvc:mapping path="/*"/> -->
		<!-- <mvc:mapping path="/**"/> --><!-- 攔截所有 -->
			
		<mvc:mapping path="/**/*.do"/><!-- 攔截指定字尾 -->
		<!-- <mvc:exclude-mapping path=""/> --><!-- 不攔截的路徑 -->
		<bean class="cn.edu.njit.interceptor.RequestInterceptor"/>
	</mvc:interceptor>
</mvc:interceptors>
           

5.測試

(1).未登入時通路其他頁面

Spring MVC攔截器

(2).使用者或密碼錯誤

Spring MVC攔截器

6.注

(1).對于需要放行(不攔截)的url需要考慮清楚;

(2).攔截器的配置可以通過springmvc.xml中顯示配置,也可通過注解實作。

(3).<mvc:mapping path=""/>中,path屬性有多種寫法,**.do,根據實際情況配置。

(4).本例中UserController、login(...)上都有@RequestMapping("/xxx"),類似于有二級路徑,是以通過'/*'則攔截不到請求。

繼續閱讀