`
zy77612
  • 浏览: 284024 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

J2EE中的异常管理及错误跟踪框架二(图)

    博客分类:
  • J2EE
阅读更多

来源:http://www.bitscn.com/pdb/java/200605/21720.html

 

  许多人认为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.

分享到:
评论

相关推荐

    J2EE项目中统一异常处理源码

    综上所述,"J2EE项目中统一异常处理源码"通过自定义异常分析和统一处理策略,实现了对14类异常的精细化管理,提升了项目的健壮性和用户体验。`ExceptionHandler.java`作为核心处理类,包含了捕获、分析和响应异常的...

    为J2EE定制一个用来处理错误的异常处理框架

    回顾一下上一个J2EE工程,是否遇到过类似错误没有记 入日志或者被多次记录的情况?是否只是因为在某处代码吃 掉了异常导致你花费无数次时间...这篇文章为你提供了在J2EE项目中通过使用错误处理框架使用一些策略的基础。

    用户管理系统 j2ee

    用户管理系统在IT行业中是至关重要的一个模块,尤其是在大型企业或互联网公司中,高效、安全的用户管理能够确保业务流程的顺畅。本系统基于Java企业级平台(J2EE)进行开发,面向初级开发者,提供了基础但实用的功能...

    基于J2EE的二手书管理系统

    5. **错误处理和日志记录**:系统应能优雅地处理异常,记录详细的日志信息,便于问题排查。 为了实现以上功能,开发者需要熟练掌握JSP语法,编写动态页面;使用Servlet处理HTTP请求,编写业务逻辑;并通过JDBC连接...

    J2EE票据管理系统源码JavaEE课程设计

    系统应能捕获并处理异常,同时将重要的操作和错误信息记录到日志文件中。 **9. 测试与调试** 在开发过程中,单元测试和集成测试是必不可少的,以确保各个功能模块的正确性和系统的整体稳定性。JUnit等测试框架可以...

    j2ee 登录小程序

    7. **SSH2框架**:在文件列表中提到了"ssh2",这可能是Secure Shell v2的缩写,也可能是指Spring Security和Hibernate的组合,这两种情况在J2EE开发中都很常见。如果是前者,SSH2可能用于远程管理或安全通信;如果是...

    J2EE.zip_J2EE_online banking_网上银行

    8. **异常处理**:J2EE提供了异常处理框架,帮助开发者捕获和处理可能出现的错误,保证系统的稳定运行。在网银系统中,异常处理是必不可少的,确保系统在遇到问题时能够及时恢复或向用户反馈错误信息。 综上所述,...

    用J2EE编写网上订餐系统

    4. **异常处理**:完善的错误处理机制,提高系统的健壮性。 5. **负载均衡**:在高并发场景下,可以使用负载均衡技术分发请求,提升系统稳定性。 **总结** 使用J2EE开发的网上订餐系统,具备良好的可扩展性和维护...

    JAVA在线考试系统DEMO源码(毕业设计 J2EE) 可直接运行.zip

    5. **会话管理(Session Management)**:J2EE系统中,会话管理用于跟踪用户状态,确保在多页面操作中用户数据的一致性。可能使用了HTTP Session或者自定义会话实现。 6. **安全控制(Security Control)**:为了...

    j2ee servlet.zip

    9. **异常处理**:Servlet应用应该正确处理异常,提供友好的错误页面,并记录错误日志。 10. **部署和测试**:了解如何在Servlet容器中部署应用,以及如何使用JUnit等工具对Servlet进行单元测试和集成测试。 通过...

    j2ee面试题大汇总

    运行时异常通常是由于程序逻辑错误导致的,例如空指针异常、数组越界异常等。这些异常可以在程序运行期间检测到,但不是强制处理的。 2. **一般异常(非运行时异常)** 非运行时异常通常由外部因素引起,例如...

    log4j错误处理(jsp,j2ee)

    Log4j是Apache软件基金会开发的一个开源日志框架,广泛应用于JSP(JavaServer Pages)和J2EE(Java 2 Platform, Enterprise Edition)应用程序中。本文将深入探讨Log4j在错误处理中的应用及其重要性。 首先,Log4j...

    J2EE——MyEclipse实现网页的登录和注册

    总之,使用MyEclipse实现J2EE的登录和注册功能涉及到多个技术层面,包括Servlet、JSP、数据库连接、会话管理和错误处理。通过实践和学习,开发者可以熟练掌握这些技能,构建出稳定、安全的Web应用。

    J2EE武功秘籍

    ### J2EE武功秘籍 #### 第一层:Java SE 技术招式辨析 **1. InputStream/OutputStream 和 Reader/Writer** - **InputStream/OutputStream**:主要用于处理字节流,适用于二进制数据的读写操作。例如,读取图片、...

    J2EE项目源码DigitalCampus数字校园

    5. **异常处理与日志记录**:项目中会设置全局的异常处理器,捕获可能出现的运行时错误,并记录到日志文件中。使用如Log4j或SLF4J这样的日志框架,可以方便地跟踪和分析系统运行状态。 6. **集成与通信**:考虑到...

    JAVA入门: J2EE的学习流程

    - 掌握如何使用调试工具来查找和修复代码中的错误。 4. **核心API**: - 学习标准库中的常用API,如集合框架、输入/输出流等。 #### 二、Web开发基础 1. **HTML/CSS/JavaScript**: - 学习网页制作的基础知识...

    j2ee的aop方式记录日志

    在J2EE应用程序开发中,日志记录是一项至关重要的任务,它可以帮助开发者追踪代码执行过程、定位错误以及分析系统性能。SSH(Struts + Spring + Hibernate)是一个经典的Java Web开发框架,而AOP(面向切面编程)是...

    J2EE面试必备

    - **状态管理**:指系统如何维护和跟踪客户端与服务器之间的交互过程中产生的状态信息。 - **会话状态**:保存用户会话期间的数据,例如登录状态等。 - **视图状态**:保存当前页面或组件的状态,以便在页面重新...

Global site tag (gtag.js) - Google Analytics