struts2中定义拦截器对访问权限进行控制

本文介绍如何在Struts框架中定义和使用权限拦截器,包括配置拦截器、实现拦截逻辑及初始化权限列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在定义权限时,首先要还是要清楚的了解到权限的分类这一概念问题:

           说的简单一点,我们使用拦截器对用户的访问权限进行控制时,总不能全部到拦截到吧,如果全部拦截,我们甚至连登陆都做不到,因此我们要清楚的知道有哪些权限需要我们来进行控制,将这些权限的action地址统一存储到我们的数据库的权限列表中,在进行数据访问时,我们只需要获取到url栏中的地址,查看这个权限是否需要我们控制,如果需要,我们再对这个权限进行控制。

        问题1:我们如何定义定义一个拦截器?

               首先在struts.xml文件进行配置

                       先声明拦截器                         

    <interceptor name="checkPrivilege" class="cn.itcast.oa.util.CheckPrivilegeInterceptor"></interceptor>

                class 为拦截器启动时对应加载的类

                           要定义拦截器类首先要继承com.opensymphony.xwork2.interceptor.AbstractInterceptor这个抽象类

                            实现类中的intercepter方法

                             package com.nan.util;
                             import com.opensymphony.xwork2.ActionInvocation;
                             import  com.opensymphony.xwork2.interceptor.AbstractInterceptor;
                             public class LanJie extends AbstractInterceptor {
                          @Override
                     public String intercept(ActionInvocation arg0) throws Exception {
                         // TODO Auto-generated method stub
                     return null;
                          }
                                    }

             问题2:我们定义好拦截器如何使用

                               首先在配置文件struts.xml中定义使用拦截器栈

                                   <interceptor-stack name="defaultStack">
                   <interceptor-ref name="checkPrivilege"></interceptor-ref>
                   <interceptor-ref name="defaultStack"></interceptor-ref>
                        </interceptor-stack>
                                   </interceptors>

                           在类中定义业务逻辑:注意业务逻辑本身还是要看这个用户有没有这个权限(登陆这种情况要特殊对待应该全部放行否则无论怎么跳都是到登陆页                                                                  面)

                                    public String intercept(ActionInvocation invocation) throws Exception {
 //获取action地址
String namespace = invocation.getProxy().getNamespace();
String actionName = invocation.getProxy().getActionName();
String privUrl = namespace + actionName;
//从session中获取当前的登陆对象
Employee employee=(Employee)ActionContext.getContext().getSession().get("employee");
//在类中定义拦截逻辑
// 判断登陆对象是否为空  
if (employee == null) {
if (privUrl.startsWith("/user_login")) { // "/user_loginUI", "/user_login"
//如果对象本身执行的就是登陆操作 直接放行
return invocation.invoke();
} else {
// 如果是其它的操作 直接跳到登陆页
return "loginUI";
}
}
//如果用户已经登录了
else {
if (employee.hasPrivilegeByUrl(privUrl)) {
// 判断当前地址栏中的action地址是否属于该用户的权限
return invocation.invoke();
} else {
// 没有改权限就跳到没有权限登录的页面
return "noPrivilegeError";
}
}
}

        //前面一开始就说了对权限进行区分,就是在  hasPrivilegeByUrl()这个方法中定义

                               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;
}
}                    

               

     上面的程序中还有一个问题:.get("allPrivilegeUrls");获得的这个collection对象在哪呢?我们让它在初始化的时候就进行加载

                                                 如何实现这个需求呢?首先我们需要知道如何实现初始化加载程序

                                                   在web.xml 文件中配置监听 注意需要配置在spring容器之后,因为我们要将对象放在spring容器中

                                                            <!-- 配置Spring的用于初始化容器对象的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>


<!--
用于做初始化工作的监听器,一定要配置到Spring的ContextLoaderListener之后,因为要用到Spring的容器对象
-->
<listener>
<listener-class>cn.itcast.oa.util.InitListener</listener-class>
</listener>                           

          要想使我们定义的InitListener类实现监听的功能,还需要实现  javax.servlet.ServletContextListener;接口,   并实现接口中的方法

package com.nan.util;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class LisennerTest implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
@Override
public void contextInitialized(ServletContextEvent sce) {

}
}

   在初始化的方法中定义我们需要进行初始化的内容:

              要初始化的内容其实就是将数据库中的内容查询出来,那么问题是我们怎么去调用查询的方法呢?通过spring获取容器对象

                    public void contextInitialized(ServletContextEvent sce) {
// 获取容器与相关的Service对象
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
PrivilegeService privilegeService = (PrivilegeService) ac.getBean("privilegeServiceImpl");


// 准备数据:topPrivilegeList
List<Privilege> topPrivilegeList = privilegeService.findTopList();
sce.getServletContext().setAttribute("topPrivilegeList", topPrivilegeList);
System.out.println("------------> 已准备数据topPrivilegeList <------------");


// 准备数据:allPrivilegeUrls
Collection<String> allPrivilegeUrls = privilegeService.getAllPrivilegeUrls();
sce.getServletContext().setAttribute("allPrivilegeUrls", allPrivilegeUrls);
System.out.println("------------> 已准备数据allPrivilegeUrls <------------");
}

            

                         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值