1.拦截器Interceptor与过滤器filter的区别:点击打开链接,实际使用中为了对不同角色(管理员,普通用户)做权限拦截,涉及不同接口controller的save,delete,get等做不同的拦截,所以使用拦截器Intercepter.
2.使用拦截器分两个步骤,实现拦截器和配置拦截器,首先实现拦截器。实现HandlerInterceptor接口。简易拦截器示意:
1.实现HandlerInterceptor接口
public class MyIntercepter implements HandlerInterceptor{
/**
* 请求方法之前执行
* 如果返回true 那么执行下一个拦截器 否则不执行
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("处理之前");
return true;
}
/**
*执行请求方法之后执行
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("处理之后");
}
/**
* 在dispatcherservlet之后执行
* 主要是清理工作
*/
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
2.配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<!--
/*拦截当前路径 例如 /add
/** 包括路径及其子路径 例如/add/add-->
<mvc:mapping path="/**"/>
<bean class="com.Intercepter.MyIntercepter"></bean>
</mvc:interceptor>
</mvc:interceptors>
3.当有不同的用户,分为不同的接口调用权限时,复杂拦截器实现:
1.实现HandlerInterceptor接口
public class MyIntercepter implements HandlerInterceptor
{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
HttpSession session = request.getSession();
User user = (User) session.getAttribute(SessionConstant.USER_INFO);
if (user == null)
{
// 此方法为:数据库根绝id查询用户角色,并保存至session中
return saveSession(user.getId(), session);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception
{}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception
{}
}
public class AuthInterceptor implements HandlerInterceptor
{
private static final Logger log = Logger.getLogger(AuthInterceptor.class);
private Set<String> resourceConfigs;//所有controller中的资源
private Set<String> resourceAuthConfigs;//后台访问对
private Set<String> viewAuthConfigs;//前台访问对
public void setResourceConfigs(Set<String> resourceConfigs)
{
this.resourceConfigs = resourceConfigs;
}
//保存用户与路径对应权限保存起来
public void setViewAuthConfigs(Set<String> viewAuthConfigs)
{
this.viewAuthConfigs = viewAuthConfigs;
String[] lst = null;
String role = null;
String viewPath = null;
for (String authConfig : viewAuthConfigs)
{
lst = authConfig.split(",");
if (lst.length == 2)
{
role = lst[0];
viewPath = lst[1];
save(role, viewPath);
}
else
{
log.error("Illegal config:" + authConfig);
}
}
}
//将property为resourceAuthConfigs的配置的角色与资源对应保存起来
public void setResourceAuthConfigs(Set<String> resourceAuthConfigs)
{
this.resourceAuthConfigs = resourceAuthConfigs;
String[] lst = null;
String role = null;
String resource = null;
String actions = null;
Set<String> resources = null;
...//与上方法类似
}
/**
* 覆盖方法/实现方法(选择其一) (功能详细描述)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
String method = request.getMethod();
String uri = request.getRequestURI();
HttpSession session = request.getSession();
String roleID = null;
String playRole = request.getParameter("playas");
//playAsRole方法为:根绝session判断用户是否有活跃角色roleId,若有返回true,若无返回false
if (playRole != null && playAsRole(session, playRole))
{
//roleID为请求的角色
roleID = playRole;
}
else
{
//roleId设为session中的角色ID,若没有则默认游客
RoleVo currUserRole = (RoleVo) session.getAttribute(SessionConstant.ACTIVE_USER_ROLE);
roleID = (null != currUserRole) ? currUserRole.getRoleId() : Role.CODE.VISITOR.value();
}
//判断角色与当前的资源是否有相应的请求权限
Boolean isAlowAccess = judge(roleID, uri, method);
if (!isAlowAccess)
{
log.warn(String.format("AuthInterceptor--role:%s,method:%s,url:%s,result:%s.", roleID, request.getMethod(),request.getRequestURL(), isAlowAccess));
if (uri.endsWith("html"))
{
response.getWriter().write("You do not have permission to access this view.");
}
else
{
response.setStatus(403);// 403 禁止访问
}
}
return isAlowAccess;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception
{
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception
{
}
}
2.配置权限
<mvc:interceptors>
<!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
<bean class="com.intercepter.MyInterceptor" />
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/**/css/**" />
<mvc:exclude-mapping path="/**/i18n/**" />
<mvc:exclude-mapping path="/**/img/**" />
<mvc:exclude-mapping path="/**/js/**" />
<mvc:exclude-mapping path="/**/views/**" />
<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
<bean class="com.intercepter.AuthInterceptor">
<property name="resourceConfigs">
<set>
<value>apps</value>
</set>
</property>
<property name="resourceAuthConfigs">
<set>
<value>admin,*,ALL</value>
<value>visitor,apps,SELECT|CREATE</value>
</set>
</property>
<property name="viewAuthConfigs">
<set>
<value>visitor,/public/*</value>
<value>visitor,/errors/*</value>
<value>admin,/admin/*</value>
</set>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
参考文献:https://blog.csdn.net/baidu_33293577/article/details/52606092