1. 抽象的类

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.登录验证

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的配置

<?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>

参考:

拦截器的基础了解

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


拦截器的详细了解

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


登录例子的思路了解

https://blog.51cto.com/983836259/1880284


正则表达式

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