基於struts的權限控制——簡單實現

struts框架中只有一個ActionServlet,但可以有多個客戶化的requestProcesscor。對於struts來說真正做控制的是RequestProecssor和Action。

其中Action的process方法最終調用的是RequestProcessor類中的process方法。

下面是該方法的源碼:

public void process(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// 如果HTTP請求方式爲post,並且contentType爲”multipart/form-data”開頭,標準的HttpServletRequest對象將被重新包裝,
// 以方便處理”multipart”類型的HTTP請求如果請求方式爲get,或正congtentType屬性不是”mulitipart”,就直接返回原始的HttpServletRequest對象.
request = processMultipart(request);
// 獲得請求的URI的路徑,這一信息可用於選擇合適的Struts Action組件.
String path = processPath(request, response);
if (path == null) {
return;
}
if (log.isDebugEnabled()) {
log.debug("Processing a '" + request.getMethod() +
"' for path '" + path + "'");
}
// 當ControllerConfig對象的locale屬性爲true,將讀取用戶請求中包含的Locale信息,然後把Locale實例保存在session範圍內.
processLocale(request, response);
// 讀取ControllerConfig對象的conttentType屬性,
// 然後調用response.setContentType(contentType)方法,設置響應結果的文檔類型和字符編碼.
processContent(request, response);
// 讀取ControllerConfig對象的nocache屬性,
// 如果nocache屬性爲true,在響應結果中將加入特定的頭參數:Pragma,Cache-Control和Expires
processNoCache(request, response);
// 該方法不執行任何操作.直接返回true.子類可以覆蓋這個方法.
// 執行客戶化的預處理請求操作.
if (!processPreprocess(request, response)) {
return;
}
this.processCachedMessages(request, response);
// 尋找和用戶請求的URI匹配的ActionMapping,如果不存在這樣的ActionMapping,則向用戶返回恰當的錯誤信息
ActionMapping mapping = processMapping(request, response, path);
if (mapping == null) {
return;
}
// 先判斷是否爲Action配置了安全角色,如果配置了安全角色,就調用isUserInRole()方法判斷當前用戶是否具備必需的角色,
// 如果不具備,就結束請求處理流程.,向用戶返回恰當的錯誤消息
if (!processRoles(request, response, mapping)) {
return;
}
// 先判斷是否爲ActionMapping配置了ActionForm,如果配置了ActionForm,就先從ActionForm的存在範圍內(request或session)尋找改ActionForm實例,
// 如果不存在,就創建一個實例,接下來把它保存在合適的範圍內,保存時使用的屬性key爲ActionMapping的name屬性。
ActionForm form = processActionForm(request, response, mapping);
// 如果爲ActionMapping配置了ActionForm,就先調用ActionForm的reset()方法,再把請求中的表單數據組裝到ActionForm中
processPopulate(request, response, form, mapping);
// 如果爲ActionMapping配置了ActionForm,並且ActionMapping的validate屬性爲true,
// 就調用ActionForm的validate()方法,如果validate方法返回的ActionErrors對象中包含ActionMessage對象,
// 說明表單驗證失敗。就把ActionErrors對象放在request範圍內,再把請求轉發到ActionMapping的input屬性指定的Web組件。
// 如果ActionForm的validate方法執行表單驗證成功,就繼續執行下面的處理流程。
try {
if (!processValidate(request, response, form, mapping)) {
return;
}
} catch (InvalidCancelException e) {
ActionForward forward = processException(request, response, e, form, mapping);
processForwardConfig(request, response, forward);
return;
} catch (IOException e) {
throw e;
} catch (ServletException e) {
throw e;
}
// Process a forward or include specified by this mapping
if (!processForward(request, response, mapping)) {
return;
}
if (!processInclude(request, response, mapping)) {
return;
}
// 先判斷是否在Action緩存中存在這個Action實例,如果沒有就新建一個Action實例,
// 把它放在Action緩存中。可以看出Action也是隻有一個實例在運行的
Action action = processActionCreate(request, response, mapping);
if (action == null) {
return;
}
// Call the Action instance itself
ActionForward forward =
processActionPerform(request, response,
action, form, mapping);
// 把你的Action的excute方法返回的ActionFoward對象作爲參數傳給它,
// processActionForward對象包的請求轉發信息來執行請求轉發或重定向。
processForwardConfig(request, response, forward);

}

下面是我自己寫的一個實際使用的類,對於一般的小型系統的權限控制個人感覺夠用:

package com.shy.test; import java.util.ArrayList; import java.util.Iterator; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.RequestProcessor; /** * @author shy.qiu * struts配置文件配置方法 * <controller * contentType="text/html;charset=utf-8" * locale="true" * nocache="true" * processorClass="com.shy.web.ShyRequestProcessor"> * </controller> */ public class ShyRequestProcessor extends RequestProcessor { // 普通用戶的權限數組 ArrayList<String> authority1 = new ArrayList<String>(); // 管理員的權限數組 ArrayList<String> authority2 = new ArrayList<String>(); public ShyRequestProcessor(){ //建議從數據庫中讀取,並放入session中 // 普通用戶權限組裝 authority1.add("TSKR0010"); authority1.add("TSKR0210"); authority1.add("TSKR0220"); authority1.add("TSKR0230"); // 管理員權限組裝 authority2.add("TSKR0310"); authority2.add("TSKR0320"); authority2.add("TSKR0330"); authority2.add("TSKR0340"); authority2.add("TSKR0350"); authority2.add("TSKR0360"); authority2.add("TSKR0370"); authority2.add("TSKR0380"); } protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) { // 通過標記位 boolean flag=true; // 權限名稱 String kengen=""; // 請求路徑 String action_path=""; try { // 獲得請求的URI的路徑,這一信息可用於選擇合適的Struts Action組件. action_path = super.processPath(request, response); // 登陸權限全都返回true if ("login".equals(action_path)) { flag = true; } else { // 得到權限名稱 if(request.getSession().getAttribute("kengen")!=null) { kengen = request.getSession().getAttribute("kengen").toString(); // 沒有任何權限 } else { request.setAttribute("Error", "你沒有該權限"); request.getRequestDispatcher("/index.jsp").forward(request,response); return false; } // 當用戶爲管理員時 if ("2".equals(kengen)) { for (Iterator<String> it = authority2.iterator();it.hasNext();) { String s_authority = (String)it.next(); if(action_path.equals(s_authority)){ flag = true; } } } // 當用戶爲普通用戶時 else if ("1".equals(kengen)) { for (Iterator<String> it = authority1.iterator();it.hasNext();) { String s_authority = (String)it.next(); if(action_path.equals(s_authority)){ flag = true; } } } } // 權限通過標記爲爲false時 if(!flag) { request.setAttribute("Error", "你沒有該權限"); request.getRequestDispatcher("/index.jsp").forward(request,response); return false; } // 權限通過標記爲爲true時 else { return true; } } catch (Exception e) { e.printStackTrace(); return false; } } }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章