欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
基于攔截器和注解實(shí)現頁(yè)面的訪(fǎng)問(wèn)權限控制


 

          在 web 系統中,經(jīng)常需要對每個(gè)頁(yè)面的訪(fǎng)問(wèn)進(jìn)行權限控制。譬如,要進(jìn)入 xx 公司的開(kāi)放 平臺, isv 需要注冊成為開(kāi)發(fā)者,開(kāi)發(fā)者的狀態(tài)有審核中、有效、凍結、拒絕、刪除等狀態(tài),然后根據不同的狀態(tài),開(kāi)發(fā)者可以訪(fǎng)問(wèn)不同的頁(yè)面。只有有效或凍結狀態(tài)可以訪(fǎng)問(wèn)只讀功能的頁(yè)面(即該頁(yè)面的訪(fǎng)問(wèn)不會(huì )造成后臺數據的變化),只有有效狀態(tài)可以訪(fǎng)問(wèn)具有寫(xiě)功能的頁(yè)面。

      如何實(shí)現該訪(fǎng)問(wèn)控制的需求呢?最直觀(guān)的做法就是:在每個(gè)頁(yè)面對應的 controller 里,都去調用查詢(xún)開(kāi)發(fā)者的服務(wù),然后判斷開(kāi)發(fā)者的狀態(tài)。

 

Java代碼  
  1. @Controller  
  2. @RequestMapping("/appDetail.htm")  
  3. public class AppDetailController {  
  4.     @RequestMapping(method = RequestMethod.GET)  
  5.     public String doGet(ModelMap modelMap, HttpServletRequest httpServletRequest) {  
  6.         //1. 開(kāi)發(fā)者有效性判斷  
  7.         Developer developer = developerManageServiceClient  
  8.             .getByCardNo(cardNo);  
  9.         if (null == developer){  
  10.             return ERROR_VM;  
  11.         }  
  12.         if (DeveloperStatus.VALID != developer.getStatus()  &&  DeveloperStatus.FREEZE != developer.getStatus()) {  
  13.             return ERROR_VM;  
  14.         }  
  15.         //2. 業(yè)務(wù)操作,此處省略  
  16.     }  
  17. }  
  18.   
  19. @Controller  
  20. @RequestMapping("/appBaseInfoEdit.htm")  
  21. public class AppBaseInfoEditController {  
  22.     @RequestMapping(method = RequestMethod.POST)  
  23.     public String modify(ModelMap modelMap, HttpServletRequest httpServletRequest,  AppBaseInfoForm appBaseInfoForm) {  
  24.         //1. 開(kāi)發(fā)者有效性判斷  
  25.         Developer developer = developerManageServiceClient  
  26.             .getByCardNo(cardNo);  
  27.         if (null == developer){  
  28.             return ERROR_VM;  
  29.         }  
  30.         if (DeveloperStatus.VALID !=  developer.getStatus()) {  
  31.             return ERROR_VM;  
  32.         }  
  33.         //2. 業(yè)務(wù)操作,此處省略  
  34.     }  
  35. }  

 

   appDetail.htm 對應的頁(yè)面需要開(kāi)發(fā)者的狀態(tài)為有效或者凍結, appBaseInfoEdit.htm 對應的頁(yè)面需要開(kāi)發(fā)者的狀態(tài)為有效。

采用這種方式有以下缺點(diǎn):

  1. 多個(gè) controller 里實(shí)現同樣的代碼,造成代碼冗余;
  2. 對于每個(gè) controller 的主體功能來(lái)說(shuō),對開(kāi)發(fā)者狀態(tài)的檢查是一個(gè)橫切關(guān)注點(diǎn),將這種關(guān)注點(diǎn)摻和在主功能里,會(huì )使得主體業(yè)務(wù)邏輯不清晰。

      所以,可以基于A(yíng)OP 將這種橫切關(guān)注點(diǎn)以攔截器的方式實(shí)現,但存在的一個(gè)問(wèn)題是,攔截器如何知道某個(gè)頁(yè)面的訪(fǎng)問(wèn)對開(kāi)發(fā)者狀態(tài)的要求呢?可以基于注解實(shí)現。譬如:

 

Java代碼  
  1. @Controller  
  2. @RequestMapping("/appDetail.htm")  
  3. @Permission(permissionTypes = { PermissionEnum.DEVELOPER_VALID })  
  4. public class AppDetailController {  
  5.     @RequestMapping(method = RequestMethod.GET)  
  6.     public String doGet(ModelMap modelMap, HttpServletRequest httpServletRequest) {  
  7.         //1. 業(yè)務(wù)操作,此處省略  
  8.     }  
  9. }  
  10.   
  11. @Controller  
  12. @RequestMapping("/appBaseInfoEdit.htm")  
  13. @Permission(permissionTypes = { PermissionEnum.DEVELOPER_VALID, PermissionEnum.DEVELOPER_FREEZE })  
  14. public class AppBaseInfoEditController {  
  15.     @RequestMapping(method = RequestMethod.POST)  
  16.     public String modify(ModelMap modelMap, HttpServletRequest httpServletRequest, AppBaseInfoForm appBaseInfoForm) {  
  17.         //1. 業(yè)務(wù)操作,此處省略  
  18.     }  
  19. }  

 

  @Permission(permissionTypes = { PermissionEnum.DEVELOPER_VALID }) ,表示開(kāi)發(fā)者的狀態(tài)必須是有效; @Permission(permissionTypes = { PermissionEnum.DEVELOPER_VALID, PermissionEnum.DEVELOPER_FREEZE }) ,表示開(kāi)發(fā)者的狀態(tài)必須是有效或者凍結。這樣,每個(gè)controller 的主體業(yè)務(wù)邏輯就清晰了。

    下面分析一下注解和攔截器是如何實(shí)現的:

    注解實(shí)現:

 

Java代碼  
  1. @Target(ElementType.TYPE)  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. public @interface Permission {  
  4.     /** 檢查項枚舉 */  
  5.     PermissionEnum[] permissionTypes() default {};  
  6.     /** 檢查項關(guān)系 */  
  7.     RelationEnum relation() default RelationEnum.OR;  
  8. }  

         RelationEnum 該枚舉表示各檢查項( permissionTypes )之間的關(guān)系, OR 表示至少需要滿(mǎn)足其中一個(gè)檢查項, AND 表示需要滿(mǎn)足所有檢查項

 

Java代碼  
  1. /** 
  2.  * 權限檢查攔截器 
  3.  *  
  4.  * @author xianwu.zhang 
  5.  * @version $Id: PermissionCheckInterceptor.java, v 0.1 2012-10-25 下午07:48:11 xianwu.zhang Exp $ 
  6.  */  
  7. public class PermissionCheckInterceptor extends HandlerInterceptorAdapter {  
  8.     /** 權限檢查服務(wù) */  
  9.     private PermissionCheckProcessor permissionCheckProcessor;  
  10.     @Override  
  11.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
  12.         Class<?> clazz = handler.getClass();  
  13.         if (clazz.isAnnotationPresent(Permission.class)) {  
  14.             Permission permission = (Permission) clazz.getAnnotation(Permission.class);  
  15.             return permissionCheckProcessor.process(permission, request,response);  
  16.         }  
  17.         return true;  
  18.     }  
  19. }  

 

Java代碼  
  1.  * 權限檢查器  
  2. *  @author xianwu.zhang  
  3.  * @version $Id: PermissionCheckProcessor.java, v 0.1 2012-11-5 下午05:13:17 xianwu.zhang Exp $  
  4.  */  
  5. public class PermissionCheckProcessor {  
  6.     public boolean process(Permission permission, HttpServletRequest request, HttpServletResponse response) {  
  7.         PermissionEnum[] permissionTypes = permission.permissionTypes();  
  8.         try {  
  9.             String cardNo = OperationContextHolder.getPrincipal().getUserId();  
  10.             HttpSession session = request.getSession(false);  
  11.          If(null != session){  
  12.                //查詢(xún)開(kāi)發(fā)者  
  13.                   Developer developer = developerManageServiceClient .getByCardNo(cardNo);  
  14.                if (null != developer &&  checkPermission(permissionTypes, permission.relation(),developer .getStatus())) {  
  15.                   return true;  
  16.                }  
  17. }  
  18.             sendRedirect(response, ISV_APPLY_URL);  
  19.             return false;  
  20.         } catch (Exception e) {  
  21.             sendRedirect(response, ISV_APPLY_URL);  
  22.             return false;  
  23.         }  
  24. }  
  25. //省略  
  26. }  
  27.      
  28.     private void sendRedirect(HttpServletResponse response, String redirectURI) {  
  29.         URIBroker uriBroker = uriBrokerManager.getUriBroker(redirectURI);  
  30.         String url = uriBroker.render();  
  31.         try {  
  32.             response.sendRedirect(url);  
  33.         } catch (IOException e) {  
  34.             logger.error("轉向頁(yè)面:" + url + "跳轉出錯:", e);  
  35.         }  
  36.     }  
  37. }  

 

     Xml 配置如下:

 

Xml代碼  
  1. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">  
  2.     <property name="interceptors">  
  3.         <list>  
  4.             <ref bean="permissionCheckInterceptor" />  
  5.         </list>  
  6.     </property>  
  7. </bean>  
  8.   
  9. <bean id="permissionCheckInterceptor"  
  10.         class="com.xxx.xxx.web.home.interceptor.PermissionCheckInterceptor" />  
  11. <bean id="permissionCheckProcessor"  
  12.         class="com.xxx.xxx.web.home.interceptor.PermissionCheckProcessor" />  

 

        還有一個(gè)小細節可以?xún)?yōu)化一下,現在是每訪(fǎng)問(wèn)一個(gè)頁(yè)面,都會(huì )經(jīng)過(guò)這個(gè)攔截器,攔截器里面都有一次 webservice 調用以查詢(xún)開(kāi)發(fā)者信息(開(kāi)發(fā)者 cardNo 和開(kāi)發(fā)者狀態(tài))。但真實(shí)場(chǎng)景中,99.99% 的情況是,用戶(hù)在同一個(gè) session 下完成所有的業(yè)務(wù),即訪(fǎng)問(wèn)的所有頁(yè)面都具有同一個(gè)sessison ,因此可以在開(kāi)發(fā)者第一次訪(fǎng)問(wèn)頁(yè)面時(shí),通過(guò) webservice 調用查詢(xún)到開(kāi)發(fā)者信息,如果權限校驗通過(guò),則將開(kāi)發(fā)者 cardNo 和開(kāi)發(fā)者狀態(tài)放在 session 里,那么在 session 未失效前, 開(kāi)發(fā)者再次訪(fǎng)問(wèn)其他頁(yè)面時(shí),可以在攔截器里先判斷目前登陸的用戶(hù)卡號是否與 session 里存儲的cardNo 相同,如果相同,則就不需要再調用 webserivce 了,可以直接取 session 里存儲的開(kāi)發(fā)者狀態(tài)來(lái)進(jìn)行權限校驗,這樣就減少了大量的不必要的 webservice 調用。

 

Java代碼  
  1. /** 
  2.     * 權限檢查器 
  3.    *  @author xianwu.zhang 
  4.     * @version $Id: PermissionCheckProcessor.java, v 0.1 2012-11-5 下午05:13:17 xianwu.zhang Exp $ 
  5.     */  
  6. public class PermissionCheckProcessor {  
  7.   
  8.     public boolean process(Permission permission, HttpServletRequest request,  
  9.                            HttpServletResponse response) {  
  10.         PermissionEnum[] permissionTypes = permission.permissionTypes();  
  11.         try {  
  12.             String cardNo = OperationContextHolder.getPrincipal().getUserId();  
  13.             HttpSession session = request.getSession(false);  
  14.             if (null != session) {  
  15.                 String developerCardNo = (String) session.getAttribute("developerCardNo");  
  16.                 if (StringUtil.isNotBlank(cardNo) && StringUtil.equals(cardNo, developerCardNo)) {  
  17.                     String status = (String) session.getAttribute("status");  
  18.                     if (checkPermission(permissionTypes, permission.relation(), status)) {  
  19.                         return true;  
  20.                     }  
  21.                 } else {  
  22.                     Developer developer = developerManageServiceClient .getByCardNo(cardNo);  
  23.                     if (null != developer  
  24.                         && checkPermission(permissionTypes, permission.relation(), developer  
  25.                             .getStatus())) {  
  26.                         session.setAttribute("status", developer.getStatus());  
  27.                         session.setAttribute("developerCardNo ", cardNo);  
  28.                         return true;  
  29.                     }  
  30.                 }  
  31.             }  
  32.             sendRedirect(response, ISV_APPLY_URL);  
  33.             return false;  
  34.         } catch (Exception e) {  
  35.             sendRedirect(response, ISV_APPLY_URL);  
  36.             return false;  
  37.         }  
  38.     }  
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
一種簡(jiǎn)單的直觀(guān)的高效的權限設計
Android 懸浮窗延時(shí)5秒返回APP問(wèn)題
java責任鏈模式及項目實(shí)際運用
自定義AOP技術(shù)實(shí)現對action方法進(jìn)行攔截并實(shí)現權限攔截
android用okhttp搭建網(wǎng)絡(luò )通訊(附服務(wù)器端代碼)
Android 使用Mobclix實(shí)現廣告盈利
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久