应该有不少人对异常处理时而清醒,时而迷糊。到了事上,就不知道是应该捕获还是应该抛出了。我就是这样踉踉跄跄的走到今天,虽然也下功夫研究过他们。下面是我对全局异常处理的一些看法。
  有多少人的网站会时不时地给大家一个异常界面?应该为数不少吧,而且有时还会觉得这样很酷,因为它可以用来调错。站在用户角度来审视一下,这个页面就显得比较沉重了。我电脑坏了?我把系统搞糟了?程序错了?如果被领导看见,他会认为这个错误不在你的控制范围之内。如果我们能够在任何异常出现的时候都给用户一个友好的提示,情况就不同了。用户会想:噢,出错了,我可能需要稍候再试。起码他认为你的程序知道自己错了。主动认错在任何情况下都不是一件坏事,程序是不会说谎的。
考虑使用errorPage,这在jsp中是页面的一个属性,如果你很懒(多数程序员都很懒),就把所有异常都交给同一个页面处理好了,当你的页面出现了异常的时候,错误页面可以取得这个异常,你可以将它保存到日志中,然后再给用户主动承认错误就行了,或许用户对你具体犯了什么错并不关心,那么只要和他说:“我错了!”就行了。在servlet中怎么办呢?我从《jsp设计》中找到了答案:
try{
  action.perform();
}catch(Throwable t){
  request.setAttribute(“javax.servlet.jsp.jspException”,t);
  RequestDispatcher rd = getServletContext().getRequestDispatcher(“/error.jsp”);
  rd.forward(request, response);
}
在jsp规范中,属性名javax.servlet.jsp.jspException是为异常对象特地保留的。这样errorPage就统一了。
  由此就牵出了另一个问题,你的工具包中的异常应该倾向于捕获还是倾向于抛出。我的观点是倾向于抛出。因为工具包一般不会仅为一个工程服务,而你并不知道下一个工程会如何处理异常。异常的处理应该是和业务相关的。即使不是工具包,这条规则同样适用,我经常像下面这样写代码:
public void load() throws SQLException{
  try{
    …  
  }finally{
    DBUtil.close(conn, stat, rs);
  }
}
如果异常太多怎么办?有时候一系列操作可能抛出n多个异常,这时候,我倾向于使用异常转译,这也是《effective java》中提倡的做法。下面是我在项目中的一个代码片断:
try{
  …做MISC订购接口请求包的解析
} catch (javax.xml.parsers.ParserConfigurationException e) {
throw new ProvisionException("解析定购请求包异常:" + e.getMessage());
} catch (org.xml.sax.SAXException e) {
throw new ProvisionException("解析定购请求包异常:" + e.getMessage());
} catch (IOException e) {
throw new ProvisionException("解析定购请求包异常:" + e.getMessage());
}分多点,真是。

解决方案 »

  1.   

    路过,和楼主做法差不多。只是不会发exception到错误页,只告诉客户出错了。
      

  2.   

    错误页是指getServletContext().getRequestDispatcher(“/error.jsp”);
      

  3.   

    to  brucejia(大碗喝酒,大块吃肉)
    与业务没关系,不一定不能抛出,只是需要做异常转译。
    尤其是第三方工具包,我曾经用过一个,当它出错的时候,就自己捕获了自己的异常,没有抛出来,使我失去了对他的控制。当然这个工具包是小公司做的,它的部分源代码我看过,水平一般。