需求:
我们在做系统的时候,使用系统的用户经常会分为很多种角色。比如什么都可以访问的admin,只能管理论坛的管理员。等等。我们系统中就遇到了权限分配的问题,那什么是权限,权限就是对系统功能的使用,功能就是开发出来的url,对功能的控制就是对url的控制,拦截器器要实现Interceptor接口,或是继承AbstractInterceptor类。
整体思路是这样的:
// 1,如果未登录
// >> 如果不是正在使用登录功能,就转到登录页面// >> 如果正在使用登录功能,就放行
// 2,如果已登录
// >> 如果有权限,就放行// >> 如果没有权限,就转到“没有权限的错误提示页面”
自定义拦截器的实现:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package cn.itcast.oa.util;
import cn.itcast.oa.domain.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class CheckPrivilegeInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
// 获取信息
User user = (User) ActionContext.getContext().getSession().get("user"); // 当前登录用户
String namespace = invocation.getProxy().getNamespace();
String actionName = invocation.getProxy().getActionName();
String privUrl = namespace + actionName; // 对应的权限URL
// 如果未登录
if (user == null) {
if (privUrl.startsWith("/user_login")) { // "/user_loginUI", "/user_login"
// 如果是去登录,就放行
return invocation.invoke();
} else {
// 如果不是去登录,就转到登录页面
return "loginUI";
}
}
// 如果已登 录,就判断权限
else {
if (user.hasPrivilegeByUrl(privUrl)) {
// 如果有权限,就放行
return invocation.invoke();
} else {
// 如果没有权限,就转到提示页面
return "noPrivilegeError";
}
}
}
}
</span>
在用户实体类中,有一个方法是根据url判断本用户是否有指定的URL权限,就是上面调用了hasPrivilegeByUrl。
<span style="font-family:KaiTi_GB2312;font-size:18px;">public boolean hasPrivilegeByUrl(String privUrl) {
// 超级管理有所有的权限
if (isAdmin()) {
return true;
}
// >> 去掉后面的参数
int pos = privUrl.indexOf("?");
if (pos > -1) {
privUrl = privUrl.substring(0, pos);
}
// >> 去掉UI后缀
if (privUrl.endsWith("UI")) {
privUrl = privUrl.substring(0, privUrl.length() - 2);
}
// 如果本URL不需要控制,则登录用户就可以使用
Collection<String> allPrivilegeUrls = (Collection<String>) ActionContext.getContext().getApplication().get("allPrivilegeUrls");
if (!allPrivilegeUrls.contains(privUrl)) {
return true;
} else {
// 普通用户要判断是否含有这个权限
for (Role role : roles) {
for (Privilege priv : role.getPrivileges()) {
if (privUrl.equals(priv.getUrl())) {
return true;
}
}
}
return false;
}
}</span>
我们还需要在Struts.xml配置文件中去声明拦截器,重新定义默认的拦截器栈,还有,是如何跳入没有权限的提示界面呢。也是在Struts.xml中配置了一个Global-result节点,不管是哪个action的访问,都可以进入。
Struts.xml:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><interceptors>
<!-- 声明拦截器 -->
<interceptor name="checkPrivilege" class="cn.itcast.oa.util.CheckPrivilegeInterceptor"></interceptor>
<!-- 重新定义默认的拦截器栈 -->
<interceptor-stack name="defaultStack">
<interceptor-ref name="checkPrivilege"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 全局的Result配置 -->
<global-results>
<result name="loginUI">/WEB-INF/jsp/userAction/loginUI.jsp</result>
<result name="noPrivilegeError">/noPrivilegeError.jsp</result>
</global-results></span>
总结:
之前在一个网上商城的项目中也用到了拦截器,是在登陆的时候判断的,是否可以登陆访问资源。拦截器的使用可以在action的前后进行一些业务处理,Struts2核心功能放在了拦截器上,这样大大增加了Struts的实用性和灵活可控。在xml中进行简单的配置就可以,前提是命名要规范。每个action都默认的继承defaultStack,如果你用了别的拦截器,还需要手动引入defaultStack。因为登录和访问权限拦截是全局的,拦截返回的结果有些也是全局的。
第二次的使用对拦截器更加熟悉了。