springMVC 基於註釋 經過攔截器來控制後臺的權限

版權聲明:本文爲博主原創文章,未經博主容許不得轉載。程序員

 

最近公司佈置了一個任務,經過springMVC註解來控制一個請求的權限;因爲以前沒有接觸過註釋控制權限,此次嘗試了;效果還不是特別好;只能進行簡單的權限管理,固然這只是初版,確定後面要修改不少方面,但願大神們多多指導;web

權限這沒用用到最近比較火的shiro框架,仍是基於RBAC模型 ,有六張表;spring

用戶表 user 角色表 菜單表 資源表  還有2張關係表 數據庫

①自定義註解(目前爲了簡單隻定義了一個註解,後期還要再加):mvc

//用於約束被描述的註解的使用範圍,當被描述的註解超出使用範圍則編譯失敗。
@Target(ElementType.METHOD)
//做用範圍爲運行時,就是咱們能夠經過反射動態獲取該註解。
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermission {
    String value() default "user";
}

②寫攔截器(注:目前尚未處理沒有權限的跳轉頁面)app

public class RequiresPermissionInterceptor extends HandlerInterceptorAdapter {
        @Autowired
        private PermissionService permissionService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {

            //經過反射獲得權限的角色
            //角色分爲三種 user:用戶 admin:管理員 superAdmin:超級管理員
            RequiresPermission permission = ((HandlerMethod) handler).getMethodAnnotation(RequiresPermission.class);
            String value = permission.value();
            System.out.print("角色"+value);

            //經過反射拿到requestMapping 裏面的value參數
            RequestMapping annotation=((HandlerMethod) handler).getMethodAnnotation(RequestMapping.class);
            System.out.print(annotation.toString());
            String[] rm= annotation.value();
            //拿到當前請求的地址
            String url =request.getServletPath();

            String  wholeUrl="";
            for (int i=0;i<rm.length;i++){
                wholeUrl = splitString(url)+rm[i];
                System.out.println("wholeUrl完整的url是:"+wholeUrl);
            }

            //沒有註明權限 或者權限爲user 則都默認爲用戶的權限
            if (permission == null || "user".equals(value) ) {
                System.out.println("我進來了");

                //得到用戶的roleType
                Integer roleType =RoleTypeConstant.ROLE_USER;
                System.out.println("用戶的roleType"+roleType);

              RoleFunction roleFunction =permissionService.findByUrlAndCode(wholeUrl,roleType);

                if(roleFunction!=null){
                    return true;
                }


            }else if ("admin".equals(value)){
                //得到管理員的roleType
                Integer roleType =RoleTypeConstant.ROLE_ADMIN;
                System.out.println("管理員的roleType"+roleType);

                RoleFunction roleFunction =permissionService.findByUrlAndCode(wholeUrl,roleType);

                if(roleFunction!=null){
                    return true;
                }


            }else if ("superAdmin".equals(value)){
                //得到超級管理員的roleType
                Integer roleType =RoleTypeConstant.ROLE_SUPER_ADMIN;
                System.out.println("超級管理員的roleType"+roleType);
                RoleFunction roleFunction =permissionService.findByUrlAndCode(wholeUrl,roleType);

                if(roleFunction!=null){
                    return true;
                }
            }
        }

        return false;

    }


    //截取字符串
    private String splitString(String url){
        //得到第二個/的下標
        int subscript= url.indexOf("/",2) ;
        System.out.println("subscript"+subscript);

        //截取第二個/前面的字符串
        String subUrl= url.substring(0,subscript);
        System.out.println("SubUrl是"+subUrl);
        return subUrl;
    }
}

注:RoleTypeConstant調用的方法框架

public class RoleTypeConstant {

    /**
     * 超級管理員帳戶
     */
    public static final Integer ROLE_SUPER_ADMIN = 1;

    /**
     * 普通管理員帳戶
     */
    public static final Integer ROLE_ADMIN = 2;

    /**
     * 普通註冊用戶帳戶
     */
    public static final Integer ROLE_USER = 3;


    public static String getTypeName(Integer roleType){
        String typeName = "";

        switch (roleType){
            case 1 :
                typeName = "超級管理員";
                break;
            case 2 :
                typeName = "普通管理員";
                break;
            case 3 :
                typeName = "普通註冊用戶";
                break;
        }

        return typeName;
    }

 

注:service層的實現ide

@Service("permissionService")
public class PermissionServiceImpl  implements PermissionService{

    @Autowired
    private PermissionDomainService permissionDomainService;
    @Override
    public RoleFunction findByUrlAndCode(String url,Integer roleType) {
        //若是地址爲直接返回用戶的權限
        if (url!=null){
        System.out.println("url" +url);
        //經過查找url得到function對象

        Function function =permissionDomainService.findFunctionByUrl(url);
            System.out.println("function" +function.getCode());

       // 經過url得到用戶惟一的code
        Integer  code = function.getCode();
            if (code!=null ){
                //經過得到code 和 roleType 判斷RoleFunction是否爲null
                //roleType 分爲三種 1:超級管理員 2:管理員 3:用戶
                RoleFunction roleFunction =permissionDomainService.findByCode(code,roleType);

                return roleFunction;
            }

        }
        return null;
    }
}

 

dao層(實現方式不一樣,這裏我只說明接口)測試

public interface PermissionDao {
    //經過url得到用戶惟一的code
    public Function queryFunctionByUrl(String url);

    //經過code 得到用戶的rolType 從而控制權限
    //roleType 分爲三種 1:超級管理員 2:管理員 3:用戶
    public RoleFunction queryByCode(Integer  code,Integer roleType);
}

 

③配置文件裏添加掃描攔截器ui

<mvc:interceptors>
    <!-- 國際化操做攔截器 若是採用基於(請求/Session/Cookie)則必需配置 -->
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
    <!-- 若是不定義 mvc:mapping path 將攔截全部的URL請求 -->

    <!--攔截器處理用戶登錄的權限 -->
    <!--<bean class="com.zhongqi.permission.Intercepter.RequiresUserInterceptor"></bean>-->
    <!--攔截器處理資源的權限 -->
    <bean class="com.zhongqi.permission.Intercepter.RequiresPermissionInterceptor"></bean>
</mvc:interceptors>

控制層的測試()

 

@Controller
@RequestMapping("/match")
public class PermissionController extends BaseController {
    @Autowired
    private PermissionService permissionService;
    /**
     * 測試 從數據庫的資源列表查找
     * user 的權限  /user/loginOut
     * 管理員特有的權限 /match/modifyMatchEvent
     * 超級管理員特有的權限
     *
     *
     * @param response
     */

    @RequiresPermission("user")
    @RequestMapping("/loginOut")
    private void  PermissionText1(HttpServletResponse response){
        JsonResponseResult result = new JsonResponseResult();

        result.setCode(1);
        result.setMsg("輸入正確");
        //公司內部封裝
        response(BaseUtils.toJsonFromObject(result), response);
    }

    @RequiresPermission("user")
    @RequestMapping("/modifyMatchEvent")
    private void  PermissionText2(HttpServletResponse response){
        JsonResponseResult result = new JsonResponseResult();


        result.setCode(1);
        result.setMsg("輸入正確");
        //公司內部封裝
        response(BaseUtils.toJsonFromObject(result), response);
    }

    @RequiresPermission("superAdmin")
    @RequestMapping("/pt3")
    private void  PermissionText3(HttpServletResponse response){
        JsonResponseResult result = new JsonResponseResult();

        result.setCode(1);
        result.setMsg("輸入正確");
        //公司內部封裝
        response(BaseUtils.toJsonFromObject(result), response);
    }

注:目前只是簡單的實現了權限控制,還有不少問題沒有解決,由於這只是一我的的想法,還有註釋裏面的參數應該能夠再豐富些。目前註釋裏面只有三個參數,或者不填;經過裏面的註釋能夠判斷這個請求是否能夠繼續下去,就是攔截器;

剛剛開始作,寫的特別low,但願大神們多多指導。後期會持續更新改版後的權限管理,歡迎你們訪問,但願給剛入手的程序員有所幫助。

                      2016 /09/09

相關文章
相關標籤/搜索