您的位置:首页 > 编程语言 > Java开发

Java Exception 应用情景(一)

2013-03-01 16:52 267 查看
Java Exception 应用情景1:用户登录

经常在登录时,遇到“用户名或密码错误”这样的提示,让人搞不清楚究竟是用户名记错了,还是密码输错了。那么为什么程序员不将这两种情况分开提示呢?

   当Control层(如,servlet)直接调用Model层的"boolean login(String username, String password)"方法,login函数在用户名密码均正确时,返回true,否则返回false。编写Control层代码的程序员可以通过判断返回 的值来判断登录是否成功。但是,这样只能知道用户是否登录成功,但万一不成功,却无法获知登录失败的原因。

按照传统的做法,有两种方式可以进行“用户名不存在”和“密码错误”的分开提示:

1、在 Control层先调用Model层的 "boolean checkUsernameExist(String username)" 方法,判断用户名是否存在,若不存在则提示“用户名不存在”。若存在则将用户名和密码一起传入Model层的login方法进行函数调用,此时如果 login方法仍返回false,说明密码错误。

优势:不用改动Model层的方法就可以进行两种提示

弊端:Control层本应负责数据的打包转发(从view层接收数据,封装后转给Model层;从Model层获得回应,将数据重新组织后传给View层显示),但现在却混入了逻辑判断,Control层的职责变得有些含糊不清。

2、改动Model层的login方法,让它的返回值可以包含多种信息(如,“int login(String userName, String password)”,返回值0代表成功,1代表)。

优势:不需要Control层事先做额外的判断,只需要分析login函数的返回值就可以知道登录是否成功,以及不成功时的原因

弊端:需要Control层的程序员查看文档来获知Model层程序员对返回值的定义,API不够友好。

现在,让我们来分析一下login的流程:

View Code

try {
userManager.login(userName, password);
// 将用户名放入session中

RequestDispatcher requestDispatcher = req.getRequestDispatcher("prepareHomePage.do");
requestDispatcher.forward(req, resp);
} catch (IllegalUserNameException e) {
// 用户名错误
String notice = "用户名错误";
req.setAttribute("notice", notice);
RequestDispatcher requestDispatcher = req.getRequestDispatcher("login.jsp");
requestDispatcher.forward(req, resp);
} catch (PasswordErrorException e) {
// 密码错误
String notice = "密码错误";
req.setAttribute("notice", notice);
RequestDispatcher requestDispatcher = req.getRequestDispatcher("login.jsp");
requestDispatcher.forward(req, resp);
} catch (FailAccessToDBException e) {
// 无法连接到数据库服务器
String notice = "网络错误,请您稍后再试";
req.setAttribute("notice", notice);
RequestDispatcher requestDispatcher = req.getRequestDispatcher("login.jsp");
requestDispatcher.forward(req, resp);
}


(这段代码有很多冗余的地方,不知道各位看官有没有好的解决方法……)

总结:

  java exception是java独特的一个元素,在我理解中,它用来保证我们将精力放在正常的业务逻辑上,一般的代码本身应该主要用来实现正常业务逻辑的执 行。在正常业务逻辑执行的过程中,会产生可预知及不可预知的意外情况,例如内存泄露属于不可预知的意外情况,参数输错属于可预知的意外情况。从前我们都将 exception想得太严重,觉得是非法参数、数组越界这些很严重的情况才会用到exception,属于“不得以而处理之”的东西。现在,我们是否应 该好好利用这个java中特别的一份子,来帮助我们更好的处理业务流程,将正常流程和意外情况分割开来进行处理,以保证正常业务需求与意外事件分离。

   使用异常还有一个好处是,它显示的声明了可能发生的意外情况。例如,在读取一个数据项是,也许给出的索引是错误的,在从前的代码中,比较细心些的程序员 会留个心眼检查一下调用的代码是否会返回null对象。有一些粗心的程序员会忘记这一点,默认对方会返回一个对象,然后就在自己的代码中直接调用该对象的 方法,从而在调试时,会莫名其妙的收到空指针异常。如果下层代码在撰写时对索引无效这一个意外情况封装了一个Checked类型的Exception,那 么上层调用的程序员就可以在IDE的提示下获知这一可能发生的意外,从而在代码中避免调用空指针的方法而导致错误。并且,上层程序员还可以视情况的恢复异 常,即使他无能为力,至少还可以再抛给上层,看看有没有人可以处理这个意外。也算是程序员之间,一种不见面的契约。

  但是使用异常会有一 个问题,即接口的耦合度变高了。原来只需要参数符合,现在还强制要求处理预见的异常,很多程序员也觉得是一种负担,代码上看起来也会不简洁。而且,如果某 一个业务模块会发生的意外很多,而针对每一个意外情况都定义一种异常的话,会导致接口抛出一长串异常,使代码变得很难看。所以,如何将性质相近的异常抽象 成一个通用的异常也很考验java程序员的功力。

  此文是抛砖引玉,向大家介绍小女对java异常的一些看法以及在工程中的一些用法。还希望大家可以多提意见,一起来讨论看看java异常应该怎么用比较合适。希望看官们可以不吝赐教,大家共同进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: