java为我们提供了非常完美的异常处理机制
从上面这幅图可以看出,Throwable是java语言中所有错误和异常的超类(万物即可抛)。它有两个子类:Error、Exception。 其中Error为错误,是程序无法处理的,如OutOfMemoryError、ThreadDeath等,出现这种情况你唯一能做的就是听之任之,交由JVM来处理,不过JVM在大多数情况下会选择终止线程。 而Exception是程序可以处理的异常。它又分为两种CheckedException(受捡异常),一种是UncheckedException(不受检异常)。其中CheckException发生在编译阶段,必须要使用try…catch(或者throws)否则编译不通过。而UncheckedException发生在运行期,具有不确定性,主要是由于程序的逻辑问题所引起的,难以排查,我们一般都需要纵观全局才能够发现这类的异常错误,所以在程序设计中我们需要认真考虑,好好写代码,尽量处理异常,即使产生了异常,也能尽量保证程序朝着有利方向发展。
checked异常: 表示无效,不是程序中可以预测的。比如无效的用户输入,文件不存在,网络或者数据库链接错误。这些都是外在的原因,都不是程序内部可以控制的。 必须在代码中显式地处理。比如try-catch块处理,或者给所在的方法加上throws说明,将异常抛到调用栈的上一层。 继承自java.lang.Exception(java.lang.RuntimeException除外)。 unchecked异常: 表示错误,程序的逻辑错误。是RuntimeException的子类,比如IllegalArgumentException, NullPointerException和IllegalStateException。 不需要在代码中显式地捕获unchecked异常做处理。 继承自java.lang.RuntimeException(而java.lang.RuntimeException继承自java.lang.Exception)。
1、添加一个错误代码汇总枚举类
package com.dhb.springmvc.exception; import org.springframework.http.HttpStatus; /** * Created by ${denghb} on 2016/8/16. * 错误代码汇总枚举 * 所有错误代码及其描述统一都在这个枚举上添加,统一管理,方便查看,并与BizException联合使用 */ public enum ErrorCode { //权限相关 ACCESS_DENIED(HttpStatus.FORBIDDEN, "ACCESS_DENIED","访问被拒绝"), //数据不存在 NOT_FOUND(HttpStatus.NOT_FOUND, "NOT_FOUND", "数据不存在"), //参数错误 BAD_REQUEST(HttpStatus.BAD_REQUEST, "BAD_REQUEST", ""), REQUIRE_ARGUMENT(HttpStatus.BAD_REQUEST, "REQUIRE_ARGUMENT", "缺少参数"), INVALID_ARGUMENT(HttpStatus.BAD_REQUEST, "INVALID_ARGUMENT", "非法参数"), EMPTY_ROLES_NOT_ALLOWED(HttpStatus.BAD_REQUEST, "EMPTY_ROLES_NOT_ALLOWED", "角色不能为空"), SERVICE_UNAVAILABLE(HttpStatus.SERVICE_UNAVAILABLE, "SERVICE_UNAVAILABLE", "服务不可用"); private HttpStatus httpStatus; private String code; private String message; private static final String PCC_CODE_PREFIX = "PCC_SERVER/"; ErrorCode(HttpStatus httpStatus, String code, String message) { setHttpStatus(httpStatus); setCode(code); setMessage(message); } public HttpStatus getHttpStatus() { return this.httpStatus; } public void setHttpStatus(HttpStatus httpStatus) { this.httpStatus = httpStatus; } public String getCode() { return PCC_CODE_PREFIX + this.code; } public void setCode(String code) { this.code = code; } public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } } 2、创建一个异常类BusinessException.java,继承RuntimeException(应该要具有扩展性): package com.dhb.springmvc.exception; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; /** * Created by ${denghb} on 2016/8/16. */ public class BizException extends RuntimeException { ResponseEntity<ErrorMessage> responseEntity; public BizException(ResponseEntity<ErrorMessage> responseEntity, Throwable cause) { super(((ErrorMessage)responseEntity.getBody()).getMessage(), cause); this.responseEntity = responseEntity; } public BizException(ErrorMessage errorMessage, HttpStatus status, Throwable cause) { this(new ResponseEntity(errorMessage, status), cause); } public BizException(String code, String message, HttpStatus status, Throwable cause) { this(new ErrorMessage(code, message), status, cause); } public BizException(String code, String message, HttpStatus status) { this(code, message, (HttpStatus)status, (Throwable)null); } } 3、异常信息封装类(具有统一性): package com.dhb.springmvc.exception; import java.io.Serializable; /** * Created by ${denghb} on 2016/8/16. */ public class ErrorMessage implements Serializable { private static final long serialVersionUID = -5401402542472113075L; private String code; private String message; private String detail; public ErrorMessage() { } public ErrorMessage(String code) { this(code, (String)null, (String)null); } public ErrorMessage(String code, String message) { this(code, message, (String)null); } public ErrorMessage(String code, String message, String detail) { this.code = code; this.message = message; this.detail = detail; } public String getCode() { return this.code; } public void setCode(String code) { this.code = code; } public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } public String getDetail() { return this.detail; } public void setDetail(String detail) { this.detail = detail; } } 4、项目模块中用到异常封装时需要继承BizException: package com.dhb.springmvc.exception; /** * Created by ${denghb} on 2016/8/16. */ public class MyBizException extends BizException { /** * code 为 errorCode的code; * HttpStatus 为 errorCode的status; * message 为 errorCode的默认message * @param errorCode 错误枚举 */ public MyBizException(ErrorCode errorCode) { super(errorCode.getCode(), errorCode.getMessage(),errorCode.getHttpStatus()); } /** * code 为 errorCode的code; * HttpStatus 为 errorCode的status; * message 为 message * @param errorCode 错误枚举 * @param message 错误消息描述 */ public MyBizException(ErrorCode errorCode, String message) { super(errorCode.getCode(), message, errorCode.getHttpStatus()); } } 5、测试类 package com.dhb.springmvc.exception; import org.junit.Test; /** * Created by ${denghb} on 2016/8/16. */ public class MyBizExceptionTest { @Test public void testMyBizException() { Object user = null; if (null == user) { throw new MyBizException(ErrorCode.NOT_FOUND); // throw new MyBizException(ErrorCode.NOT_FOUND, "该用户不存在"); } } } 运行结果:
在这里要区分throw和throws。 throws是方法抛出异常。在方法声明中,如果添加了throws子句,表示该方法即将抛出异常,异常的处理交由它的调用者,至于调用者任何处理则不是它的责任范围内的了。所以如果一个方法会有异常发生时,但是又不想处理或者没有能力处理,就使用throws吧! 而throw是语句抛出异常。它不可以单独使用,要么与try…catch配套使用,要么与throws配套使用。
也可以参考这篇文章:http://www.cnblogs.com/chenssy/p/3453039.html
