国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

J2EE中的異常管理及錯誤跟蹤框架二(圖)

2019-11-18 12:27:04
字體:
來源:轉載
供稿:網友

  許多人認為SUN應該在每應用的基礎上給J2EE框架內置插入所有容器的鉤子。這樣就答應自定義錯誤處理方案、安全及更多可安裝的功能,而不需要依靠特定廠商的方案和框架。不幸地是,SUN并沒有在EJB規范中提供這樣的機制。既然如此,我們只有拿出AOP這個強有力的工具來增加異常處理。我們選擇的aspectWerkz框架,可以如下使用方面:
  
  public class EJBExceptionHandler implements AroundAdvice {PRivate ExceptionHandler handler;
  public EJBExceptionHandler() {   handler = ConfigHelper.getEJBExceptionHandler();
  }  public Object invoke(JoinPoint joinPoint) throws Throwable {   Log log = LogFactory.getLog(joinPoint.getEnclosingStaticJoinPoint().getClass().getName());
  log.debug("EJB Exception Handler bean context aspect!!");
  try {     return joinPoint.proceed();
  } catch (RuntimeException e) {     handler.handle(Thread.currentThread(), e);
  } catch (Error e) {     handler.handle(Thread.currentThread(), e);
  }   return null;
  }}
  
  實際的處理器是通過ConfigHelper類來配置和獲取的。假如RuntimeException 或者Error在業務邏輯處理過程被拋出時,處理器就會被請求處理了。
  
  DefaultEJBExceptionHandler序列化任何并非來自SUN核心包異常的堆棧信息到專門的SerializableException中,這從好的方面來看,可以將在遠程客戶端不存在的類的異常的堆棧以任意方式傳播,另一方面,這會丟失原始的異常。
  
  假如客戶端是遠程的,EJB容器忠實地捕捉RuntimeException或Error并將他包在java.rmi.RemoteException中,否則使用javax.ejb.EJBException。為了在最低程度保持來源的精確性及堆棧信息,框架在BusinessDelegates剝離傳送異常并重新拋出原始異常。
  
  Rampart框架的BusinessDelegate類提供一個EJB無關的接口給客戶端,而在內部包含本地或遠程的EJB接口。BusinessDelegate類從EJB實現類中用XDoclet生成的,他遵循圖4中UML圖結構:
  
 J2EE中的異常治理及錯誤跟蹤框架二(圖)(圖一)

  BusinessDelegate提供所有來自源EJB實現類的業務方法并代理給相應的LocalProxy或RemoteProxy類。在內部兩個代理類處理EJB相關的異常,從而隱藏了BusinessDelegate的實現細節。下面的代碼是來自某個LocalProxy類的方法:
  
  public java.lang.String someOtherMethod() {  try {   return serviceInterface.someOtherMethod();
  } catch (EJBException e) {   BusinessDelegateUtil.throwActualException(e);
  }  return null;
  // Statement is never reached}
  
  serviceInterface變量代表EJB本地接口。任何被容器拋出的EJBException實例意味著一個未知錯誤被BusinessDelegateUtil類捕捉和處理,如下面發生的操作:
  
  public static void throwActualException(EJBException e) {  doThrowActualException(e);
  }private static void doThrowActualException(Throwable actual) {  boolean done = false;
  while(!done) {   if(actual instanceof RemoteException) {     actual = ((RemoteException)actual).detail;
  } else if (actual instanceof EJBException) {     actual = ((EJBException)actual).getCausedByException();
  } else {     done = true;
  }  }  if(actual instanceof RuntimeException) {   throw (RuntimeException)actual;
  } else if (actual instanceof Error) {   throw (Error)actual;
  }}
  
  actual異常被摘出并重新被拋出給頂層的客戶端異常處理器。當異常到達處理器時,堆棧信息會是來自服務端且包含實際錯誤的原始異常。沒有多余的客戶端信息被附加。
  
  Swing異常處理器
  
  JVM為每一個控制線程提供了缺省的頂層異常處理器。在異常發生時,處理器輸出Error或RuntimeException的堆棧信息到System.err并且結束線程。這種處理行為與用戶的要求相差很遠而且從調試的觀點來看也不是很優雅。我們需要一種機制在保存堆棧信息和為以后調試預備的唯一請求ID的同時答應通知用戶。“創建基于J2EE的應用范圍用戶會話”描述了如何在所有層都可以形成這樣的請求ID。
  
  J2SE1.4以前的版本,在Thread實例中未捕捉的異常將導致其所在的ThreadGroup的uncaughtException()方法被執行。在應用中控制異常處理的簡單方法是繼續ThreadGroup類,重寫uncaughtException()方法,并且確認所有Thread在自定義的ThreadGroup類的實例中啟動。
  J2SE5提供了一種更方便的機制答應在Thread類的實例中安裝UncaughtExceptionHandler實現。處理器在未捕捉的異常到達Thread實例的運行方法中通過回調機制起作用。我們的框架基于J2SE1.3+,因而使用基于繼續ThreadGroup的方法:
  
  private static class SwingThreadGroup extends ThreadGroup {  private ExceptionHandler handler;  public SwingThreadGroup(ExceptionHandler handler) {   super("Swing ThreadGroup");   this.handler = handler;  }  public void uncaughtException(Thread t, Throwable e) {   handler.handle(t, e);  }}
  
  在上面的代碼斷中SwingThreadGroup類重寫了uncaughtException()方法并傳遞Thread實例及拋出Throwable給配置的異常處理器。
  
  在我們在客戶端層控制所有未處理的異常之前還需要做些技巧性的工作。為了使用這個方案有效,所有線程必須與我們的SwingThreadGroup實例關聯。這可以通過生成一個主Thread實例并且通過Runnable實現傳遞SwingThreadGroup實例,這樣就可以執行整個程序了。所有來自這個新的主Thread實例的Thread實例自動加入SwingThreadGroup實例,因此當非強制異常被拋出時會觸發新的異常處理器。
  
 J2EE中的異常治理及錯誤跟蹤框架二(圖)(圖二)
點擊查看大圖

  如圖5中框架在SwingExceptionHandlerController類中實現這個邏輯。應用提供SwingMain接口的實現和異常處理器給控制器。然后控制器必須啟動,同時舊的主線程可以加入新線程中并等待結束。下面的代碼顯示演示應用如何完成這種任務。createAndShowGUI()方法構成實際的應用內容用來初始化Swing組件及傳送控制給用戶。
  
  public DemoApp() {   SwingExceptionHandlerController.setHandler(new DefaultSwingExceptionHandler());
  SwingExceptionHandlerController.setMain(new SwingMain() {   public Component getParentComponent() {     return frame;
  }   public void run() {     createAndShowGUI();
  }  });
  SwingExceptionHandlerController.start();
  SwingExceptionHandlerController.join();
  }
  
  防衛的底線現在在Swing層了,但我們依然需要提供有意義的信息給用戶。演示應用提供了一種更基本的實現,可以簡單地顯示國際化信息的對話框和唯一的用來給支持人員的請求ID。一個更復雜的錯誤處理器可以發送email、SNMP信息或者包含請求ID的技術支持。要害的是客戶端及服務端日志可以用請求ID來過濾從而使基于每個請求的定位更精確。
  
J2EE中的異常治理及錯誤跟蹤框架二(圖)(圖三)

  圖6顯示合并的Swing客戶端及J2EE服務端日志為請求ID為1cffeb4:feb53del38:-7ff6提供精確的定位。注重堆棧信息僅包含來自服務端的信息,而異常就是來自那兒。
  
  雖然為獨立的J2SE應用增加異常處理的底層框架是基礎的,但當我們移植到基于網頁客戶端時還是需要作些改變。
  
  WAR異常處理器
  
  網頁應用在J2EE開發中是比較幸運的,擁有自己安裝異常處理的能力。通過web.xml配置描述文檔,異常和HTTP錯誤可以在servlets或jsp中映射到錯誤頁面。看一下下面的來自web.xml文檔中的示例片斷:
  
  <servlet>
  <servlet-name>ErrorHandlerServlet</servlet-name>
  <servlet-class>dk.rhos.fw.rampart.util.errorhandling.ErrorHandlerServlet</servlet-class></servlet><servlet-mapping>  <servlet-name>ErrorHandlerServlet</servlet-name>
  <url-pattern>/errorhandler</url-pattern></servlet-mapping><error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/errorhandler</location></error-page>
  
  這些標記指示所有未處理的異常會轉到/errorhandler這個URL去,在這里就是映射到ErrorHandlerServlet類。這是一個專門的servlet用來作為網頁組件與異常處理框架之間的橋梁。當來自網頁應用的未處理異常到達servlet容器中,一組包含異常信息的參數會被增加到HttpServletRequest實例并且傳遞給ErrorHandlerServlet類的service方法。下面的片斷例示了service方法:
  
  ...private static final String CONST_EXCEPTION = "javax.servlet.error.exception";
  ...protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
  throws ServletException, IOException {
  Throwable exception = (Throwable)httpServletRequest.getAttribute(CONST_EXCEPTION);
  ExceptionHandler handler = ConfigHelper.getWARExceptionHandler();
  handler.handle(Thread.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安达市| 石阡县| 财经| 德化县| 日喀则市| 吉林市| 阿拉尔市| 改则县| 浮山县| 明光市| 昌邑市| 株洲县| 偃师市| 孙吴县| 广河县| 富阳市| 普兰县| 南阳市| 伊宁市| 曲周县| 霍山县| 岑巩县| 兴化市| 钟山县| 定远县| 温州市| 长汀县| 建宁县| 凤阳县| 宁晋县| 仙游县| 都昌县| 东莞市| 古交市| 屏山县| 安乡县| 凤城市| 阿瓦提县| 黔江区| 尼木县| 庆安县|