在spring 3.0甚礎上,起來越多的用到了注解,從前的攔截器在配置文件中需要這樣配置
- <beans...>
- ...
- <bean id="measurementInterceptor"
- class="com.apress.springrecipes.court.web.MeasurementInterceptor"/>
- <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="interceptors">
- <list>
- <ref bean="measurementInterceptor"/>
- </list>
- </property>
- ...
- </bean>
- <bean class="org.springframework.web.servlet.mvc.support
- .ControllerClassNameHandlerMapping">
- <property name="interceptors">
- <list>
- <ref bean="measurementInterceptor"/>
- </list>
- </property>
- </bean>
- ....
- </beans>
現在用注解只需要這樣:
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/*/*.shtml"/>//映射路徑后綴名
- <bean class="x.x.x.filter.SessionFilter"/>//自定義攔截器
- </mvc:interceptor>
- </mvc:interceptors>
SessionFilter.java代碼:
- public class SessionFilter implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
- // 后台session控制
- Object user=request.getSession().getAttribute("username");
- String returnUrl = request.getRequestURI();
- if(null==user){
- if(returnUrl.equals("/public/getImg.shtml")||returnUrl.equals("/public/checkLogin.shtml")||returnUrl.equals("/public/login.shtml")||returnUrl.equals("/public/logOut.shtml")){
- return true;
- }else{
- response.setContentType("text/html");
- response.setCharacterEncoding("utf-8");
- PrintWriter out = response.getWriter();
- StringBuilder builder = new StringBuilder();
- builder.append("<script type=\"text/javascript\" charset=\"UTF-8\">");
- builder.append("alert(\"請重新登陸!\");");
- builder.append("window.location.href=\"/public/login.shtml\";");
- builder.append("</script>");
- out.print(builder.toString());
- out.close();
- return false;
- }
- }
- return true;
- }
- @Override
- public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
- }
- @Override
- public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse response, Object o, Exception e) throws Exception {
- }
- /**
- * @param request
- * @return Create Date:2013-6-5
- * @author Shine
- * Description:獲取IP
- */
- private String getIpAddr(HttpServletRequest request) {
- String ip = request.getHeader("x-forwarded-for");
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("Proxy-Client-IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("WL-Proxy-Client-IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getRemoteAddr();
- }
- return ip;
- }
- }
這個攔截器的目的就是:用戶所屬的session不存在后進行對控制器請求的攔截,使跳轉到首頁。對於HandlerInterceptor這個類這里不多說,網上有的可能說的更好,這里只簡單說下它的三個方法,preHandle、postHandle和afterCompletion。
(1 )preHandle(WebRequest request) 方法。該方法將在請求處理之前進行調用,也就是說會在Controller 方法調用之前被調用。這個方法跟HandlerInterceptor 中的preHandle 是不同的,主要區別在於該方法的返回值是void ,也就是沒有返回值,所以我們一般主要用它來進行資源的准備工作,比如我們在使用Hibernate 的時候可以在這個方法中准備一個Hibernate 的Session 對象,然后利用WebRequest 的setAttribute(name, value, scope)把它放到WebRequest 的屬性中。這里可以說說這個setAttribute 方法的第三個參數scope ,該參數是一個Integer類型的。在WebRequest 的父層接口RequestAttributes 中對它定義了三個常量:
SCOPE_REQUEST :它的值是0 ,代表只有在request 中可以訪問。
SCOPE_SESSION :它的值是1 ,如果環境允許的話它代表的是一個局部的隔離的session,否則就代表普通的session,並且在該session范圍內可以訪問。
SCOPE_GLOBAL_SESSION :它的值是2 ,如果環境允許的話,它代表的是一個全局共享的session,否則就代表普通的session,並且在該session 范圍內可以訪問。
(2 )postHandle(WebRequest request, ModelMap model) 方法。該方法將在請求處理之后,也就是在Controller 方法調用之后被調用,但是會在視圖返回被渲染之前被調用,所以可以在這個方法里面通過改變數據模型ModelMap 來改變數據的展示。該方法有兩個參數,WebRequest 對象是用於傳遞整個請求數據的,比如在preHandle 中准備的數據都可以通過WebRequest 來傳遞和訪問;ModelMap 就是Controller 處理之后返回的Model 對象,我們可以通過改變它的屬性來改變返回的Model 模型。
(3 )afterCompletion(WebRequest request, Exception ex) 方法。該方法會在整個請求處理完成,也就是在視圖返回並被渲染之后執行。所以在該方法中可以進行資源的釋放操作。而WebRequest 參數就可以把我們在preHandle 中准備的資源傳遞到這里進行釋放。Exception 參數表示的是當前請求的異常對象,如果在Controller中拋出的異常已經被Spring 的異常處理器給處理了的話,那么這個異常對象就是是null 。
參考:http://haohaoxuexi.iteye.com/blog/1750680