您的位置:首页 > 编程语言 > Java开发

springmvc的HandlerInterceptor的简单了解(登录例子)

2017-12-06 16:25 253 查看
抽象的类

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

登录例子的思路了解

http://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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java springmvc interceptor