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;
}
}
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 responseEntity;
public BizException(ResponseEntity 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);
}
}
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;
}
}
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());
}
}
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