Struts1运用Java注解实现简单的权限控制

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 权限控制,注解类
 * 生成策略:运行时 
 * 注解位置:方法 
 * @author wangxx
 *
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface <span style="font-family: Arial, Helvetica, sans-serif;">SystemPrivilegeAnnotation </span>
{
    String[] privilegeValue();// 权限值
}

然后,根据前面的分析,重写RequestProcessor的processActionPerform方法。根据注释应该也能看的明白。

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.RequestProcessor;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.actions.MappingDispatchAction;

/**
 * 权限管理器
 * 
 * 
 * 步骤:
 * 1、要判断调用的是action的哪个方法,通过反射
 *  一般action有三种方式:
 *      第一,直接继承Action的action,那么方法名就是“execute”;
 *      第二,继承DispatchAction的action,那么方法名就是request域中对应的mapping中的parameter;
 *      第三,继承MappingDispatchAction的action,那么方法名就是mapping中的parameter
 *  通过反射得到调用action的哪个方法
 * 2、判断调用的方法上面有没有注解,也就是调用这个方法需不需要权限,
 *  不需要,调用超类的processActionPerform;
 *  需要的话,检查用户的权限是否contains这个权限,是就放行,不是不放行
 * 
 * @author wangxx
 *
 */
public class PrivilegController extends RequestProcessor {

    /*
     * 断点在ActionServlet的dopost方法上, 发现是processActionPerform调用的action
     * 
     * @see
     */
    @Override
    protected ActionForward processActionPerform(HttpServletRequest request,
            HttpServletResponse response, Action action, ActionForm form,
            ActionMapping mapping) throws IOException, ServletException {

        //判断权限
        if (!systemPrivilege(request, action, mapping)) {
            ActionMessages messages = new ActionMessages();
            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
                    "error.no.permission"));
            saveErrors(request, messages);
            //request.setAttribute("org.apache.struts.action.ERROR", "您没有权限进行当前操作!");
            //重定向到login
            // request.setAttribute("toUrl", SiteURL.getUrlByKey("logon"));
            return mapping.findForward("nonpermission");
        }
        return super.processActionPerform(request, response, action, form,
                mapping);
    }

    // 权限判断方法,返回true说明当前用户有权限调用当前方法
    private boolean systemPrivilege(HttpServletRequest request, Action action,
            ActionMapping mapping) {
        // 拿到方法的名字
        String currentMethodName = getCurrentMethodName(request, action,
                mapping);
        // 拿出方法中的注解信息
        SystemPrivilegeAnnotation systemPrivilegeAnnotation = getMethodSystemPrivilegeAnnotation(
                action, currentMethodName);
        // 如果注解信息为空说明当前方法不需要任何权限
        if (systemPrivilegeAnnotation == null) {
            return true;
        }

        //有注解,即需要权限
        // 根据注解信息建立权限对象,即当前方法所需权限
        String[] privilegeValue = systemPrivilegeAnnotation.privilegeValue();
        // 拿出当前用户--也可以存在session,总之这一步是为了取得当前登录者的信息
        UserInfo userInfo = (UserInfo) request.getSession().getAttribute(
                ConstApp.SESSION_USERINFO);
        String userRole = userInfo.getUserRole();

        //循环,将当前用户的所有权限逐个与当前方法所需权限相比较
        for (String role : privilegeValue) {
            if(role.equals(userRole)){
                return true;
            }
        }

        return false;
    }

    /**
     * 取得当前action方法的名字
     * 
     * @param request
     * @param action
     * @param mapping
     * @return
     */
    private String getCurrentMethodName(HttpServletRequest request,
            Action action, ActionMapping mapping) {
        // 继承DispatchAction的action,那么方法名就是request域中对应的mapping中的parameter
        if (DispatchAction.class.isAssignableFrom(action.getClass())) {
            return request.getParameter(mapping.getParameter());
        }
        // 继承MappingDispatchAction的action,那么方法名就是mapping中的parameter
        if (MappingDispatchAction.class.isAssignableFrom(action.getClass())) {
            return mapping.getParameter();
        }
        // 直接继承Action的action,那么方法名就是“execute”;
        return "execute";
    }

    /**
     * 通过反射得到action方法的注解信息
     * @param action
     * @param methodName
     * @return
     */
    private SystemPrivilegeAnnotation getMethodSystemPrivilegeAnnotation(
            Action action, String methodName) {
        try {
            // 第二个参数是所求方法的参数列表
            Method method = action.getClass()
                .getMethod(methodName,new Class[] { ActionMapping.class,
                        ActionForm.class, HttpServletRequest.class,HttpServletResponse.class });
            if (method != null) {
                if (method.isAnnotationPresent(SystemPrivilegeAnnotation.class)) {
                    return method.getAnnotation(SystemPrivilegeAnnotation.class);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 显示错误消息
     * @param request
     * @param errors
     */
    protected void saveErrors(HttpServletRequest request, ActionMessages errors)
    {
        if(errors == null || errors.isEmpty())
        {
            request.removeAttribute("org.apache.struts.action.ERROR");
            return;
        } else
        {
            request.setAttribute("org.apache.struts.action.ERROR", errors);
            return;
        }
    }

}

第三,别忘了在配置文件struts-config.xml添加controller。

<controller processorClass="common.PrivilegController" contentType="text/html;chatset=utf-8">
</controller>

最后,在需要权限的Action中添加注解就可以。privilegeValue中设置权限值即可。

/**
 * 用户密码修改初期化
 * 
 * @author wang
 *
 */
public class ChangePasswordAction extends Action{

    /*
     * 用户密码修改初期化
     * 
     * @see
     */
    @SystemPrivilegeAnnotation(privilegeValue = {"0","1","2","3","4"})
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        。。。。。
    }
}

至此,Struts1利用Java注解进行权限控制就基本完成了,思路基本就是如此,方法不一定最好,但是实现需求就好!
最后,这只是在工作中遇到的一个小问题,不一定具有普遍性,自己能力也有限,目前实现的方式就是这样,如果想到好的会做补充。

相关推荐