一、概述
在我們的系統中,很多時候都用到了權限。最簡單的權限就是登錄。登錄了,我就可以自己的相關信息;沒有登錄,就不能看到。
目前比較流行的權限框架就是apache shiro和spring security,大家在選擇時比較青睞apache shiro,因為spring security的攔截器過多,導致性能下降。
筆者在搭建系統時也是選擇了Apache shiro。在權限框架中,最常用的兩個地方是:
1、在controller層,使用@RequiresPermissions注解,標識這個鏈接只能是擁有這個權限的用戶才能使用。
2、在jsp中,使用<shiro:hasPermission>標簽,標識着擁有這個權限的用戶才能夠展示標簽中的內容。
筆者在搭建系統時,由於采用了集群,session統一用redis管理,在使用shiro框架時,重寫了shiro的sessionDAO,CRUD都在redis中。
在使用shiro的過程中,筆者發現一個request請求,在shiro的session管理中調用了40多次redis。雖然redis的性能非常好,但是調用40多次也沒有必要。
所以,筆者基於java注解和jsp標簽簡單的實現了權限框架,它有一定的局限性,不過大家可以進行擴展。
二、jsp標簽
在這一篇中,先向大家介紹jsp的權限標簽。
首先,編寫jsp標簽的實現類,如下:
public class HasAnyPermission extends TagSupport { @Setter@Getter private String permissions; @Override public int doStartTag() throws JspException { HttpSession session = pageContext.getSession(); String[] arrPermissions = permissions.split(",");
//用戶是否登錄 if (UserSessionUtil.isLogin(session)){ Set<String> hasPermissions = (Set<String>) session.getAttribute(SESSION_ATTR_PLAT_PERMISSION);
//用戶是否分配了權限 if(CollectionUtils.isNotEmpty(hasPermissions)){ for (String psermission : arrPermissions){
//用戶分配的權限中,是否包含該權限 if (hasPermissions.contains(psermission)){ return TagSupport.EVAL_BODY_INCLUDE; } } } return TagSupport.SKIP_BODY; }else { return TagSupport.SKIP_BODY; } } }
在這里,permissions為標簽中傳過來的權限,可以為多個,使用“,”隔開,這個可以大家可以擴展。
例如:自定義分隔符。這里就不詳細介紹了;多個權限間的“或”,“與”關系等。
在jsp當中,標簽都是成對出現的,在開始標簽時,將會執行doStartTag()方法,對應的在結束標簽時,將執行doEndTag()方法,上面的類中沒有寫出doEndTag()方法,將會執行父類TagSupport 中的doEndTag()方法。
doStartTag()方法中的具體邏輯這里不做介紹,無非就是判斷這個用戶有沒有這個權限。最關鍵的是return的內容:
EVAL_BODY_INCLUDE:如果返回這個,則標簽包含的內容會展示出來。
SKIP_BODY :標簽包含的內容不會展示。
其次,創建tld文件
在 webapp/WEB-INF/ 下,創建taglib目錄,並在taglib目錄中,創建xxx.tld文件,如下:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.1.2</tlib-version> <jsp-version>1.2</jsp-version> <short-name>Apache Shiro</short-name> <uri>/WEB-INF/taglib/xxx</uri> <!-- 配置成tld文件的目錄,xxx為tld文件的文件名 --> <description>Apache Shiro JSP Tag Library.</description> <tag> <name>hasAnyPermissions</name> <!--標簽的名稱 --> <tag-class>com.rent.common.shiro.HasAnyPermission</tag-class> <!-- 實現的類,上面編寫的HasAnyPermission類 --> <body-content>JSP</body-content> <attribute> <!--傳入參數--> <name>permissions</name> <!--參數名稱--> <required>true</required> <!--是否必傳--> <rtexprvalue>true</rtexprvalue> <!--是否可用jsp表達式--> </attribute> </tag> </taglib>
uri的參數需要在jsp中引用,tag的name屬性是標簽的名稱,permissions是變量的名稱,由jsp中傳入,而且必傳。
最后,標簽的使用
在jsp的頭部引入自定義標簽,如下:
<%@taglib prefix="pm" uri="/WEB-INF/taglib/xxx"%>
uri為tld文件中配置的uri,prefix是標簽的前綴,可以自定義,我們定義成pm。
權限標簽的使用,如下:
<pm:hasAnyPermissions permissions="show">哈哈</pm:hasAnyPermissions>
當我們在編譯器中敲入 <pm:,就會出現提示,hasAnyPermissions就是我們在tld文件中定義的name,permissions是需要的權限,而且必傳。
這樣,當用戶擁有“show”這個權限時,將會展示出“哈哈”,沒有“show”權限時,不會展示。
至此,jsp的自定義權限標簽就介紹完了,還請大家多多指教。下一篇將會介紹controller中的權限注解的實現。