熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

SSH集成框架下真正實現Spring AOP攔截功能

2013-11-23 20:30:41  來源: Java開源技術 

  問題的提出

  在Struts框架下有三種類型的Action控制器分別是MappingDispatchActionDispatchAction和Action他們是依次繼承最終執行的execute方法但MappingDispatchActionDispatchAction的子類中沒有execute方法只有參數指定的具體方法而這些方法是被MappingDispatchActionDispatchAction本類的execute方法調用執行特別注意的是它是通過反射機制來做的(大家可以看看DispatchAction類的源代碼)所以這些被反射調用的方法是不能被Spring AOP攔截的因此也就無法利用切面編程實現權限控制了

  解決方法

  巴巴運動網通過覆蓋DelegatingRequestProcessor控制器的processActionPerform方法是一種理想的解決方案但嚴格來說並不是AOP切面編程方法因此筆者僅從學習AOP切面編程的角度來提出本文章對於實用性筆者極力推薦巴巴運動網的方案

  本方法解決思想

  覆蓋execute方法再模仿DispatchAction反射調用具體的方法

  實現Spring AOP攔截點開始攔截配置描述的范圍內的程序

  在切入點程序中再次實現反射機制獲取執行方法上的權限配置信息

  根據權限信息決定放行還是返回

  最終既可以攔截到execute方法也可以得到具體方法中的權限注解配置信息以本BBS系統為例

  第一步凡繼承於DispatchAction的類都覆蓋execute方法

  

  @Override
public ActionForward execute(ActionMapping mapping ActionForm form
HttpServletRequest request HttpServletResponse response) throws Exception {
return superexecute(mapping form request response);
}


//假如這個action中有一個具體的方法
@Privilege(userType=PrivilegeTypeAdminmessage=需管理員權限!)
public ActionForward addUI(ActionMapping mapping ActionForm form
HttpServletRequest request HttpServletResponse response) throws Exception {
CategoryForm categoryForm = (CategoryForm)form;
categoryFormsetTitle(新增分類);
return mappingfindForward(addUI);
}

  第二步做自己的權限配置

  看上面addUI方法上的注解應該可以理解這些配置

  

  @Retention(RetentionPolicyRUNTIME)
@Target(ElementTypeMETHOD)
public @interface Privilege {
String message() default 您沒有權限執行該操作請登錄後重試!;
PrivilegeType userType();
}

  配置中有個字字段是枚舉源碼如下

  

  public enum PrivilegeType {
LoginUser{
public String getName(){
return 所有登錄用戶;
}
public int getValue(){
return ;
}
}

LoginUserSelf{
public String getName(){
return 登錄用戶自己;
}
public int getValue(){
return ;
}
}

Moderator{
public String getName(){
return 版主;
}
public int getValue(){
return ;
}
}

Admin{
public String getName(){
return 管理員;
}
public int getValue(){
return ;
}
};

public abstract String getName();
public abstract int getValue();
}

  第三步實現AOP切入編程

  

  @Aspect
@Component()
public class PrivilegeAction {

//攔截comzjh包下(含子包)所有類能返回ActionForward類型的方法
@Around(execution(orgapachestrutsactionActionForward comzjh**()))
public Object validatePrivilege(ProceedingJoinPoint pjp) throws Throwable{

// 從攔截的方法中參數中得到四個對象
ActionMapping mapping = (ActionMapping) pjpgetArgs()[];
ActionForm form = (ActionForm) pjpgetArgs()[];
HttpServletRequest request = (HttpServletRequest) pjpgetArgs()[];
HttpServletResponse response = (HttpServletResponse) pjpgetArgs()[];

//從攔截點處獲取它所處的類名並經過反射取得權限配置信息
Class dispatchAction = ClassforName(pjpgetSignature()getDeclaringTypeName()); Object obj = dispatchActionnewInstance(); String mappingParament = mappinggetParameter()==null ? execute : requestgetParameter(mappinggetParameter()); Method method = objgetClass()getDeclaredMethod(mappingParament
ActionMappingclass
ActionFormclass
HttpServletRequestclass
HttpServletResponseclass); Privilege privilege = methodgetAnnotation(Privilegeclass);

//如果方法上沒有配置權限信息直接放行
if(privilege==null)
return (ActionForward)pjpproceed();

//否則必須是登錄用戶進行第一關粗粒度攔截
User user = WebUtilgetUserInSession(request);
if(user==null){
requestsetAttribute(message ssage());
return mappingfindForward(message);
} //再根據用戶類型進行細粒度攔截
switch(privilegeuserType()getValue()){
//當權限為PrivilegeTypeLoginUserSelf(登錄用戶自己例如更新文章必須是自
//己的文章才有權限更新)時須從數據庫裡取得用戶對象再和session中用
//戶匹配這個沒有實現
case :
if(!usergetUsername()equals(數據庫裡取得某文章的用戶名)){
requestsetAttribute(message ssage());
return mappingfindForward(message);
}
break;
//版主權限攔截這個沒有實現
case :
requestsetAttribute(message ssage());
return mappingfindForward(message);
//管理員權限從application取得管理員用戶名再匹配session登錄用戶是否相等
case :
String admin = ((SystemProperty)requestgetSession()getServletContext()getAttribute(config))
getAdminUsername();
if(!usergetUsername()equals(admin)){
requestsetAttribute(message ssage());
return mappingfindForward(message);
}
break;
}
//當上面沒有攔住表示權限允許放行
return (ActionForward)pjpproceed();
}
}

  以上細粒度攔截屬業務邏輯不妨礙本文所述的AOP切面編程筆者僅僅是為學習AOP真正用在真實項目的權限攔截方案不太成熟


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28601.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.