springMVC:HandlerInterceptor攔截器的使用


 

1.使用背景

Web項目中需要判斷http接口用戶Post上來的數據是否合法,如果不合法要另做處理,用戶Post上來的數據是Json形式的,我們用了@RequestBody標記自動將json形式的提交封裝為一個Model對象,這樣一來,我們就不能判斷在自動封裝過程中是否出現了異常,此時便想起了springMVC中的interceptor,用於處理請求之前,做一些處理,我們可以取消@RequestBody標記,然后在interceptor中取得請求體,檢查是否符合json要求,即是不是一個valid interceptor,但是這里出現了一個問題: 
httpServletRequest的請求內容,只能被讀取一次,在interceptor中讀取了的話,在controller中便不能讀取了,解決方式是,讀取到的請求內容存起來,然后在controller中直接使用。 
這里用到了interceptor的一種,HandlerInterceptor,可以寫一個小例子來記一下是怎么使用的!

2.HandlerInterceptor概述

在SpringMVC 中定義一個Interceptor是比較非常簡單,主要有兩種方式: 
第一種:實現HandlerInterceptor 接口,或者是繼承實現了HandlerInterceptor 接口的類,例如HandlerInterceptorAdapter; 
第二種:實現Spring的WebRequestInterceptor接口,或者是繼承實現了WebRequestInterceptor的類。 
現在主要結合一個例子說一下第一種方式:實現HandlerInterceptor接口。 
HandlerInterceptor接口主要定義了三個方法: 
1. boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handle)方法:該方法將在請求處理之前進行調用,只有該方法返回true,才會繼續執行后續的Interceptor和Controller,當返回值為true 時就會繼續調用下一個Interceptor的preHandle 方法,如果已經是最后一個Interceptor的時候就會是調用當前請求的Controller方法; 
2.void postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法:該方法將在請求處理之后,DispatcherServlet進行視圖返回渲染之前進行調用,可以在這個方法中對Controller 處理之后的ModelAndView 對象進行操作。 
3.void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法:該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執行,該方法將在整個請求結束之后,也就是在DispatcherServlet 渲染了對應的視圖之后執行。用於進行資源清理。

3.簡單的一個例子:

1.xml需要配置:兩種配置方式(對所有的請求記性攔截,對特定的請求進行攔截)

<mvc:interceptors> <!--對所有的請求記性攔截--> <!--<beans:bean class="com.sunp.common.interceptor.Myinterceptor"/>--> <!--對特定的請求進行攔截--> <mvc:interceptor> <mapping path="/kfc/brands/brand1/*"/> <beans:bean class="com.sunp.common.interceptor.Myinterceptor"/> </mvc:interceptor> </mvc:interceptors> 

2.interceptors類

package com.sunp.common.interceptor; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.mkyong.common.model.Shop; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; /** * Created by hzsunpeng on 2016/6/14. */ public class Myinterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("preHandle run!"); return true; } public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("postHandle run!"); } public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("afterCompletion run!"); } }

3.controller類(為了使用@Controller @PathVariable @ResponseBody注釋等需要加一些配置文件,這里不再列出)

package com.sunp.common.controller; import com.sunp.common.model.Shop; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; /** * Created by hzsunpeng on 2016/6/7. */ @Controller @RequestMapping("/kfc/brands") public class JSONController { @RequestMapping(value = "/brand1/{name}",method = RequestMethod.GET) public @ResponseBody Shop getShopInJSON(@PathVariable String name) { Shop sp = new Shop(); sp.setName(name); sp.setStaffName(new String[]{"Staffname1","Staffname2"}); System return sp; } //測試用 @RequestMapping(value = "/json",method = RequestMethod.POST) public String index(HttpServletRequest request) { return "index"; } }

4.model Shop類

package com.sunp.common.model; import java.io.Serializable; /** * Created by hzsunpeng on 2016/6/7. */ public class Shop implements Serializable { private String name; private String[] staffName; public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getStaffName() { return staffName; } public void setStaffName(String[] staffName) { this.staffName = staffName; } }

 

運行結果:

這里寫圖片描述 
控制台輸出: 
這里寫圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM