springmvc的HandlerInterceptor的簡單瞭解(登陸例子)

  1. 抽象的類html

package com.book.admin.interceptor;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * @author liweihan
 *
 */
public abstract class AbstractInterceptor implements HandlerInterceptor{
	
	private static Logger logger = LoggerFactory.getLogger(AbstractInterceptor.class);
	
	//不須要攔截的連接
	protected static List<String> excludeActionList = new ArrayList<String>();
	
	static {
        excludeActionList.add("^/(login|static)(/)?(.+)?$");
        excludeActionList.add("^/(flush|test|site_map)(/)?(.+)?$");     //redis data flush
        excludeActionList.add("^/app/(flush|info.json|apkinfo.json)(/)?(.+)?$");    //前端接口http://m.tv.sohu.com/app
        excludeActionList.add("^/(hikeapp)(/)?(.+)?$");        //須要拉起客戶端的專輯數據訪問接口
        excludeActionList.add("^/(cooperation|activity|api|open|mobile|mb)(/)?(.+)?$");
        excludeActionList.add("^/(activity|api|open|mobile|mb)(/)?(.+)?$");
        excludeActionList.add("^/(test)(/)?(.+)?$");
	}

	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
//		logger.debug(" ====== prehandle !");
//		logger.info(" ======= URI:{}",request.getRequestURI());
		request.setAttribute("uri", request.getRequestURI());//爲了突出顯示選中的連接
		for(String excludeUrl : excludeActionList) {
			if(Pattern.matches(excludeUrl, request.getRequestURI())) {
				return true;
			}
		}
		return innerPreHandle(request, response, handler);
	}
	
	protected abstract boolean innerPreHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
//		logger.debug(" ====== postHandle !");
	}

	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
//		logger.debug(" ====== afterCompletion !");
	}
}


   2.權限過濾
前端

package com.book.admin.interceptor;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.util.WebUtils;

import com.book.core.model.AdminFunctions;
import com.book.core.model.AdminRight;
import com.book.core.model.User;
import com.book.core.service.AdminFunctionsService;
import com.book.core.service.AdminRightService;
import com.book.core.utils.Constants;

/**
 * 用戶權限過濾
 * @author liweihan
 *
 */
public class FunctionsInterceptor extends AbstractInterceptor{
	
	private static Logger logger = LoggerFactory.getLogger(FunctionsInterceptor.class);
	
	@Autowired
	private AdminRightService adminRightService;
	@Autowired
	private AdminFunctionsService adminFunctionsService;
	
	//登陸後不須要攔截的連接
	protected static List<String> excludeActionList = new ArrayList<String>();
	
	static {
        excludeActionList.add("^/(index|admin/user|admin/myinfo)(/)?(.+)?$");
        excludeActionList.add("^/(book/del|book/detail.json|book/addorupdate)(/)?(.+)?$");
	}

	@Override
	protected boolean innerPreHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		try {
			User user = (User) WebUtils.getSessionAttribute(request, Constants.ADMIN_SESSION_USER_KEY);
			if (user == null) {
				response.sendRedirect("/login");
				return false;
			}
			
			//查找該用戶的權限
			AdminRight adminRight = adminRightService.getObjByUserName(user.getName());
			if (adminRight == null) {
				return true;
			}
			
			List<AdminFunctions> menus = null;
			if (adminRight.getIsAdmin() == 1) {
				menus = adminFunctionsService.getAll(); 
				
				request.setAttribute("menus", menus);
				request.setAttribute("isAdmin", adminRight.getIsAdmin());
				return true;
			} else {
				String right = adminRight.getRights();
				if (StringUtils.isNotBlank(right)) {
					String[] rs = right.split(",");
					List<Integer> listId = null;
					
					if (rs != null && rs.length > 0) {
						listId = new ArrayList<Integer>();
						for (int i = 0; i < rs.length; i++) {
							if (StringUtils.isNotBlank(rs[i])) {
								listId.add(Integer.valueOf(rs[i]));
							}
						}
					}
					
					//查詢
					menus = adminFunctionsService.getObjByIds(listId);
				}
				for(String excludeUrl : excludeActionList) {
					if(Pattern.matches(excludeUrl, request.getRequestURI())) {
						request.setAttribute("menus", menus);
						request.setAttribute("isAdmin", adminRight.getIsAdmin());
						return true;
					}
				}
				//對權限進行過濾,不能輸入URL就能夠訪問
				if (menus != null && menus.size() > 0) {
					for(AdminFunctions adminFunctions : menus) {
						if (request.getRequestURI().startsWith(adminFunctions.getUrl())) {
							logger.info(" ====== request.getRequestURI():{},table-url:{}",request.getRequestURI(),adminFunctions.getUrl());
							request.setAttribute("menus", menus);
							request.setAttribute("isAdmin", adminRight.getIsAdmin());
							return true;
						}
					}
				}
			}
			response.sendRedirect("/login");
			return false;
		} catch (Exception e) {
			logger.error(" ====== get AdminRight error!",e);
			e.printStackTrace();
		}
		
		return false;
	}

}

   3.登陸驗證java

package com.book.admin.interceptor;

import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.util.WebUtils;

import com.book.core.model.PersistentLogins;
import com.book.core.model.User;
import com.book.core.service.PersistentLoginsService;
import com.book.core.service.UserService;
import com.book.core.utils.Constants;
import com.book.core.utils.CookieUtil;
import com.book.core.utils.EncryptionUtil;


/**
 * 登陸驗證攔截器
 * @author liweihan
 *
 */
public class LoginInterceptor extends AbstractInterceptor{
	
	private static Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);
	@Autowired
	private PersistentLoginsService persistentLoginsService;
	@Autowired
	private UserService userService;

	@Override
	protected boolean innerPreHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		
		User user = (User) WebUtils.getSessionAttribute(request, Constants.ADMIN_SESSION_USER_KEY);
		if (user != null) {
			//已登陸
			return true;
		} else {
			//從cookie中取值
			Cookie cookie = CookieUtil.getCookie(request, Constants.RememberMe_Admin);
			if (cookie != null) {
				String cookieValue = EncryptionUtil.base64Decode(cookie.getValue());
				String[] cValues = cookieValue.split(":");
				if (cValues.length == 2) {
					String userNameByCookie = cValues[0];//獲取用戶名
					String uuidByCookie = cValues[1];//獲取UUID值
					
					//到數據庫中查詢自動登陸記錄
					PersistentLogins pLogins  = persistentLoginsService.getObjByUUID(uuidByCookie);
					if (pLogins != null) {
						String savedToken = pLogins.getToken();
						
						//獲取有效時間
						Date savedValidTime = pLogins.getValidTime();
						Date currentTime = new Date();
						
						//若是還在有效期內,記錄判斷是否能夠自動登陸
						if (currentTime.before(savedValidTime)) {
							User u = userService.getUserByName(userNameByCookie);
							if (u != null) {
								Calendar calendar = Calendar.getInstance();
								calendar.setTime(savedValidTime);
								
								// 精確到分的時間字符串
								String timeString = calendar.get(Calendar.YEAR) + "-" + calendar.get(Calendar.MONTH)
										+ "-" + calendar.get(Calendar.DAY_OF_MONTH) + "-"
										+ calendar.get(Calendar.HOUR_OF_DAY) + "-" + calendar.get(Calendar.MINUTE);
								// 爲了校驗而生成的密文
								String newToken = EncryptionUtil.sha256Hex(u.getName() + "_" + u.getPassword() + "_"
										+ timeString + "_" + Constants.salt);
								
								// 校驗sha256加密的值,若是不同則表示用戶部分信息已被修改,須要從新登陸
								if (savedToken.equals(newToken)) {
									//爲了提升安全性,每次登陸以後都更新自動登陸的cookie值
									String uuidNewString = UUID.randomUUID().toString();
									String newCookieValue = EncryptionUtil.base64Encode(u.getName() + ":" + uuidNewString);
									CookieUtil.editCookie(request, response, Constants.RememberMe_Admin, newCookieValue, null);
									
									//同時更新數據
									pLogins.setSeries(uuidNewString);
									pLogins.setUpdateTime(new Date());
									persistentLoginsService.updateByObj(pLogins);
									
									//將用戶加到session中,不退出瀏覽器時只須要判斷session便可
									WebUtils.setSessionAttribute(request, Constants.ADMIN_SESSION_USER_KEY, u);
									
									//校驗成功,這次攔截操做完成
									return true;
								} else {
									//用戶信息部分被修改,刪除cookie並清空數據庫中的記錄
									CookieUtil.delCookie(response, cookie);
									persistentLoginsService.delObjById(pLogins.getId());
								}
							}
						} else {
							// 超過保存的有效期,刪除cookie並清空數據庫中的記錄
							CookieUtil.delCookie(response, cookie);
							persistentLoginsService.delObjById(pLogins.getId());
						}
					}
				}
			}
			
			try {
				response.sendRedirect("/login?src=" + URLEncoder.encode(request.getRequestURI(), "UTF-8"));
			} catch (Exception e) {
				logger.error(" ===== loginInterceptor error ,url:{}{}",request.getRequestURL(),request.getRequestURI(),e);
			} 
			return false;
		}
	}

}

   4.spring-mvc-servlet.xml的配置web

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation=" 
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context-3.0.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
	
	<!-- 指定一個包讓其自動掃描 -->
	<context:component-scan base-package="com.book.admin.controller"/>

	<mvc:annotation-driven/>
	
	<!-- 下面註釋的部分表示:強調全部的請求都要通過springmvc框架 -->
    <mvc:default-servlet-handler/>
	
	<!-- 放行了以/static/開始的請求 -->
	<mvc:resources location="/static/" mapping="/static/**"/> 
	
	<!-- 當一個方法徹底是爲了跳轉時,咱們能夠省略該方法,而在此寫一個配置就好了
	<mvc:view-controller path="/index" view-name="index"/>
	<mvc:view-controller path="/main" view-name="main"/>
	<mvc:view-controller path="/success" view-name="success"/> 
	<mvc:view-controller path="/index" view-name="main"/>
	<mvc:view-controller path="/" view-name="main"/> 
	<mvc:view-controller path="/admin/myinfo" view-name="myinfo"/>-->
	<!-- 
	<mvc:view-controller path="/book" view-name="book"/>
	 -->
	
	<mvc:interceptors>
		<bean class="com.book.admin.interceptor.LoginInterceptor"></bean>
		<bean class="com.book.admin.interceptor.FunctionsInterceptor"></bean>
		<!--  
		<mvc:interceptor>  
	        <mvc:mapping path="/test/number.do"/>  
	        <bean class="com.host.app.web.interceptor.LoginInterceptor"/>  
	    </mvc:interceptor>  
	    -->
	</mvc:interceptors>
	
	<!-- 配置springmvc的視圖解析器 -->
	<bean id="viewResolver" 
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="suffix" value=".jsp"/>
		<property name="prefix" value="/WEB-INF/views/"/>
	</bean>
	
	<!-- 文件上傳解析器   -->
	<bean id="multipartResolver" 
	    class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
	    <property name="maxUploadSize" value="100000"/> 
	</bean>
</beans>

參考:
正則表達式

攔截器的基礎瞭解redis

http://blog.csdn.net/sunp823/article/details/51694662 spring


攔截器的詳細瞭解數據庫

http://jinnianshilongnian.iteye.com/blog/1670856 apache


登陸例子的思路瞭解
json

http://www.javashuo.com/article/p-usywspvx-hd.html


正則表達式

http://www.cnblogs.com/sparkbj/articles/6207103.html


springmvc的攔截器和過濾器的區別

http://blog.csdn.net/xiaoyaotan_111/article/details/53817918


java Web中的過濾器Filter和interceptor的理解

http://www.jianshu.com/p/39c0cfe25997

相關文章
相關標籤/搜索