我们把系统运行中可能出现的异常分为五种:数据访问异常、业务处理异常、数据校验异常、操作权限异常、其他运行时异常。
数据访问异常发生在系统的持久层(系统的持久层使用Hibernate实现),例如读写数据库时发生的主键冲突、外键约束、SQL语法错误等异常。持久层抛出的异常是java.sql包和org.hibernate包中的异常对象。对于持久层异常,统一由系统的异常捕获组件负责捕获和处理。不允许开发人员在DaoHibernateImpl类中捕获任何异常,不允许在系统的任何代码中对持久层抛出的异常进行捕获。
业务处理异常发生在系统的业务层,业务处理异常用来描述业务处理过程中发生的业务状态的错误。例如:业务层要新增某条记录前,先根据该条记录的主键查询数据库,如果发现已经存在数据,就抛出业务处理异常表示该条业务数据已经存在,如果业务层在新增记录前没有先查询,那么系统必然抛出数据访问异常。虽然在这两种情况下都可以提示用户新增操作失败,但业务处理异常明显要比数据访问异常包含更多的业务处理信息,可以更清楚的提示用户。数据访问异常是与业务处理无关的底层的JDBC异常。
数据校验异常发生在WEB层和业务层,WEB层接收到用户请求后校验HttpServletRequest对象中的数据,如果校验失败,则应该抛出数据校验异常DataVerifyException。如果在业务层对DTO的数据校验失败,那么也应该抛出数据校验异常。
操作权限异常发生在系统对用户的业务操作权限、数据操作权限进行校验的时候,操作权限异常表示该用户不具有该项业务的操作权限。如果用户登录后由于长时间不操作而引起的会话失效也抛出操作权限异常PermissionException。
其他运行时异常通常不是我们主动抛出的,这些异常主要有对象空指针异常、数组索引超边界异常、不合法参数异常等。其他运行时异常主要发生在系统的开发阶段,由于编码不严谨而引起,当系统稳定运行后很少会抛出这种异常。系统代码没有显式的针对这些异常对象做处理,所有这些异常例如:NullPointerException、ClassCastException、IndexOutOfBoundsException等都直接向外抛出,系统对这些异常统一按照java.lang.RuntimeException异常处理。不允许开发人员对java.lang.RuntimeException异常和其子类异常进行捕获和处理。
业务处理异常、数据校验异常、操作权限异常都继承公共父类BaseException。系统在各层抛出的异常都由核心层的异常处理组件捕获和处理。