因?yàn)橐阋粋€(gè)簡單的權(quán)限系統(tǒng),所以最近我進(jìn)行了一些設(shè)計(jì)和實(shí)現(xiàn)。經(jīng)過研究,根據(jù)業(yè)務(wù)需求,決定使用一個(gè)二級菜單和自定義標(biāo)簽來實(shí)現(xiàn)權(quán)限的控制。
首先來解決這款二級菜單,當(dāng)然實(shí)現(xiàn)自己也肯定能實(shí)現(xiàn),但是別人做好了自己就用吧。
其他技術(shù)你可以訪問我的博客:http://cuisuqiang.iteye.com/
這個(gè)控件叫 chromemenu,官方網(wǎng)站是http://www.dynamicdrive.com/
,當(dāng)然我的附件里面已經(jīng)帶了一個(gè),你可以直接下載看一下。
使用很簡單,就是幾個(gè)層和超鏈接,正好我可以控制層和超鏈接的顯示來實(shí)現(xiàn)權(quán)限控制。
我們來定義一個(gè)標(biāo)簽web-html.tld:
<?xml version="1.0" encoding="UTF-8"?>
<!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.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>html</short-name>
<tag>
<name>resourceUrl</name>
<tag-class>com.nms.taglib.ResourceUrl</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>key</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>href</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>rel</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>note</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>isModule</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
在web.xml中配置一下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 自定義標(biāo)簽 開始 -->
<jsp-config>
<taglib>
<taglib-uri>/tld/web-html</taglib-uri>
<taglib-location>
/WEB-INF/tlds/web-html.tld
</taglib-location>
</taglib>
</jsp-config>
<!-- 自定義標(biāo)簽 結(jié)束 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
看一下實(shí)現(xiàn)類:
package com.nms.taglib;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* @說明 菜單生成
* @author 崔素強(qiáng)
*/
@SuppressWarnings("serial")
public class ResourceUrl extends BodyTagSupport {
@Override
public int doStartTag() throws JspException {
try {
// 從開放的接口取得是否允許Key資源的輸出
boolean isCheck = true;
if(isCheck){
StringBuffer results = new StringBuffer("");
if("true".equals(isModule)){
results.append("<li>");
}
results.append("<a ");
if (href != null) {
results.append(" href=\"");
results.append(href);
results.append("\"");
}
if (rel != null) {
results.append(" rel=\"");
results.append(rel);
results.append("\"");
}
results.append(">");
results.append(note);
results.append("</a>");
if("true".equals(isModule)){
results.append("</li>");
}
pageContext.getOut().write(results.toString());
}
} catch (IOException ex) {
throw new JspTagException("錯(cuò)誤");
}
return EVAL_BODY_INCLUDE;
}
@Override
public int doEndTag() throws JspException {
return EVAL_PAGE;
}
//權(quán)限驗(yàn)證標(biāo)記
protected String key;
// 實(shí)際連接地址
protected String href;
// 對應(yīng)的下拉板塊
protected String rel;
// 是否是總標(biāo)記
protected String isModule;
// 文字
protected String note;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
public String getRel() {
return rel;
}
public void setRel(String rel) {
this.rel = rel;
}
public String getIsModule() {
return isModule;
}
public void setIsModule(String isModule) {
this.isModule = isModule;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
/**
* doStartTag()方法是遇到標(biāo)簽開始時(shí)會(huì)呼叫的方法,其合法的返回值是EVAL_BODY_INCLUDE與SKIP_BODY,前者表示將顯示標(biāo)簽間的文字,后者表示不顯示標(biāo)簽間的文字
* doEndTag()方法是在遇到標(biāo)簽結(jié)束時(shí)呼叫的方法,其合法的返回值是EVAL_PAGE與SKIP_PAGE,前者表示處理完標(biāo)簽后繼續(xù)執(zhí)行以下的JSP網(wǎng)頁,后者是表示不處理接下來的JSP網(wǎng)頁
* doAfterBody(),這個(gè)方法是在顯示完標(biāo)簽間文字之后呼叫的,其返回值有EVAL_BODY_AGAIN與SKIP_BODY,前者會(huì)再顯示一次標(biāo)簽間的文字,后者則繼續(xù)執(zhí)行標(biāo)簽處理的下一步
* EVAL_BODY_INCLUDE:把Body讀入存在的輸出流中,doStartTag()函數(shù)可用
* EVAL_PAGE:繼續(xù)處理頁面,doEndTag()函數(shù)可用
* SKIP_BODY:忽略對Body的處理,doStartTag()和doAfterBody()函數(shù)可用
* SKIP_PAGE:忽略對余下頁面的處理,doEndTag()函數(shù)可用
* EVAL_BODY_BUFFERED:申請緩沖區(qū),由setBodyContent()函數(shù)得到的BodyContent對象來處理tag的body,如果類實(shí)現(xiàn)了BodyTag,那么doStartTag()可用,否則非法
* EVAL_BODY_AGAIN:請求繼續(xù)處理body,返回自doAfterBody(),這個(gè)返回值在你制作循環(huán)tag的時(shí)候是很有用的
* 預(yù)定的處理順序是:doStartTag()返回SKIP_BODY,doAfterBodyTag()返回SKIP_BODY,doEndTag()返回EVAL_PAGE
* 如果繼承了TagSupport之后,如果沒有改寫任何的方法,標(biāo)簽處理的執(zhí)行順序是:doStartTag() ->不顯示文字
* ->doEndTag()->執(zhí)行接下來的網(wǎng)頁 如果您改寫了doStartTag(),則必須指定返回值,
* 如果指定了EVAL_BODY_INCLUDE,則執(zhí)行順序是:doStartTag()->顯示文字->doAfterBodyTag()->doEndTag()->執(zhí)行下面的網(wǎng)頁
*/
}
你要關(guān)注這行代碼:
boolean isCheck = true;
在使用時(shí),你要根據(jù) KEY 去判斷是否顯示某個(gè)菜單,具體實(shí)現(xiàn)就看你的了。
然后我們在JSP頁面中進(jìn)行使用:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/tld/web-html" prefix="html"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>菜單示例</title>
<link rel="stylesheet" type="text/css" href="chromestyle.css" />
<script type="text/javascript" src="chrome.js"></script>
</head>
<body>
<div class="chromestyle" id="chromemenu">
<ul>
<html:resourceUrl href="#" key="" note="Model001" isModule="true"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="Model002" isModule="true"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="Model003" isModule="true" rel="dropmenu1"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="Model004" isModule="true" rel="dropmenu2"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="Model005" isModule="true" rel="dropmenu3"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="Model006" isModule="true" rel="dropmenu4"></html:resourceUrl>
</ul>
</div>
<!--1st drop down menu -->
<div id="dropmenu1" class="dropmenudiv">
<html:resourceUrl href="#" key="" note="a1"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="a2"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="a3"></html:resourceUrl>
</div>
<!--2nd drop down menu -->
<div id="dropmenu2" class="dropmenudiv" style="width: 150px;">
<html:resourceUrl href="#" key="" note="b1"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="b2"></html:resourceUrl>
</div>
<!--3rd drop down menu -->
<div id="dropmenu3" class="dropmenudiv" style="width: 150px;">
<html:resourceUrl href="#" key="" note="c1"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="c2"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="c3"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="c4"></html:resourceUrl>
</div>
<!--4rd drop down menu -->
<div id="dropmenu4" class="dropmenudiv" style="width: 150px;">
<html:resourceUrl href="#" key="" note="d1"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="d2"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="d3"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="d4"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="d5"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="d6"></html:resourceUrl>
<html:resourceUrl href="#" key="" note="d7"></html:resourceUrl>
</div>
<script type="text/javascript">
cssdropdown.startchrome("chromemenu");
</script>
</body>
</html>
如果是一級菜單,那么要設(shè)置:
isModule="true"
運(yùn)行你看到了所有的菜單,你可以自己控制顯示那個(gè)菜單。

這個(gè)權(quán)限就是很簡單,就是根據(jù)某個(gè)Key去判斷能否訪問那個(gè)資源。當(dāng)然在實(shí)際中應(yīng)該是你請求的連接,這樣再定義一個(gè)Filter去過濾所有請求,就能實(shí)現(xiàn)不能通過地址欄直接訪問該資源。