非保姆教程
整体思路: 1、通过@ControllerAdvice和@ExceptionHandler 注解实现全局异常 2、按照规范实现和填充其他细节
首先全局捕捉异常
package **
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.EncryptedDocumentException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.nio.file.AccessDeniedException;
@Slf4j
@ControllerAdvice
@ResponseBody
@Qualifier("globalExceptionAdvice")
public class GlobalExceptionAdvice {
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(MyException.class)
public MyResponse MyException(MyException e) {
return MyResponse.error("异常文字提醒", HttpStatus.BAD_REQUEST.value());
}
}
自定义异常实现 我们可以借鉴已经实现的异常,来使自定义的异常更加规范
package com.**
import com.**.commons.enums.IErrorCode;
public class MyException extends RuntimeException {
private int code;
private String message;
public MyException(IErrorCode code) {
this.code = code.getCode();
this.message = code.getDesc();
}
public MyException(IErrorCode code, String message) {
this.code = code.getCode();
this.message = message;
}
public MyException(final int code, final String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
public void setCode(final int code) {
this.code = code;
}
public void setMessage(final String message) {
this.message = message;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof MyException)) {
return false;
} else {
MyException other = (MyException)o;
if (!other.canEqual(this)) {
return false;
} else if (this.getCode() != other.getCode()) {
return false;
} else {
Object this$message = this.getMessage();
Object other$message = other.getMessage();
if (this$message == null) {
if (other$message != null) {
return false;
}
} else if (!this$message.equals(other$message)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof MyException;
}
public int hashCode() {
int PRIME = true;
int result = 1;
int result = result * 59 + this.getCode();
Object $message = this.getMessage();
result = result * 59 + ($message == null ? 43 : $message.hashCode());
return result;
}
public String toString() {
return "MyException(code=" + this.getCode() + ", message=" + this.getMessage() + ")";
}
}
以下是spring-web定义的一些异常可以参考
response实现
package **
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
@ApiModel
public class MyResponse<T> implements Serializable {
@ApiModelProperty(
value = "返回状态码,10000代表成功",
example = "10000"
)
private int bizcode;
@ApiModelProperty(
value = "返回消息,当状态码为非10000,该字段为异常信息",
example = ""
)
private String bizmsg;
@ApiModelProperty(
value = "返回的数据",
example = ""
)
private T data;
private String sign;
private long timestamp;
private String postToken;
public MyResponse(String bizmsg, T data, int bizcode) {
this(bizcode, bizmsg, data, (String)null);
}
public MyResponse(int bizcode, String bizmsg, T data, String postToken) {
this.bizcode = MyEnumCode.SUCCESS.getStatus();
this.bizmsg = "操作成功";
this.timestamp = System.currentTimeMillis();
this.bizcode = bizcode;
this.bizmsg = bizmsg;
this.data = data;
this.postToken = postToken;
this.timestamp = System.currentTimeMillis();
}
public MyResponse(T data) {
this("", data, CommonErrorCode.SUCCESS.getStatus());
}
public MyResponse() {
this("", (Object)null, CommonErrorCode.SUCCESS.getStatus());
}
public static MyResponse ok() {
return new MyResponse();
}
public static <T> MyResponse ok(T data) {
return new MyResponse(data);
}
public static <T> MyResponse<T> ok(String msg, T data) {
return new MyResponse(msg, data, CommonErrorCode.SUCCESS.getStatus());
}
public static MyResponse error() {
return new MyResponse("操作失败", (Object)null, CommonErrorCode.ERROR.getStatus());
}
public static MyResponse error(String msg) {
return new MyResponse(msg, (Object)null, CommonErrorCode.ERROR.getStatus());
}
public static MyResponse error(String msg, int bizcode) {
return new MyResponse(msg, (Object)null, bizcode);
}
}
关于响应状态,jdk8中有一个枚举类来定义 包package org.springframework.http下的HttpStatus
CONTINUE(100, "Continue"),
SWITCHING_PROTOCOLS(101, "Switching Protocols"),
PROCESSING(102, "Processing"),
CHECKPOINT(103, "Checkpoint"),
OK(200, "OK"),
CREATED(201, "Created"),
ACCEPTED(202, "Accepted"),
NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information"),
NO_CONTENT(204, "No Content"),
RESET_CONTENT(205, "Reset Content"),
PARTIAL_CONTENT(206, "Partial Content"),
MULTI_STATUS(207, "Multi-Status"),
ALREADY_REPORTED(208, "Already Reported"),
IM_USED(226, "IM Used"),
MULTIPLE_CHOICES(300, "Multiple Choices"),
MOVED_PERMANENTLY(301, "Moved Permanently"),
FOUND(302, "Found"),
@Deprecated
MOVED_TEMPORARILY(302, "Moved Temporarily"),
SEE_OTHER(303, "See Other"),
NOT_MODIFIED(304, "Not Modified"),
@Deprecated
USE_PROXY(305, "Use Proxy"),
TEMPORARY_REDIRECT(307, "Temporary Redirect"),
PERMANENT_REDIRECT(308, "Permanent Redirect"),
BAD_REQUEST(400, "Bad Request"),
UNAUTHORIZED(401, "Unauthorized"),
PAYMENT_REQUIRED(402, "Payment Required"),
FORBIDDEN(403, "Forbidden"),
NOT_FOUND(404, "Not Found"),
METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
NOT_ACCEPTABLE(406, "Not Acceptable"),
PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required"),
REQUEST_TIMEOUT(408, "Request Timeout"),
CONFLICT(409, "Conflict"),
GONE(410, "Gone"),
LENGTH_REQUIRED(411, "Length Required"),
PRECONDITION_FAILED(412, "Precondition Failed"),
PAYLOAD_TOO_LARGE(413, "Payload Too Large"),
@Deprecated
REQUEST_ENTITY_TOO_LARGE(413, "Request Entity Too Large"),
URI_TOO_LONG(414, "URI Too Long"),
@Deprecated
REQUEST_URI_TOO_LONG(414, "Request-URI Too Long"),
UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
REQUESTED_RANGE_NOT_SATISFIABLE(416, "Requested range not satisfiable"),
EXPECTATION_FAILED(417, "Expectation Failed"),
I_AM_A_TEAPOT(418, "I'm a teapot"),
@Deprecated
INSUFFICIENT_SPACE_ON_RESOURCE(419, "Insufficient Space On Resource"),
@Deprecated
METHOD_FAILURE(420, "Method Failure"),
@Deprecated
DESTINATION_LOCKED(421, "Destination Locked"),
UNPROCESSABLE_ENTITY(422, "Unprocessable Entity"),
LOCKED(423, "Locked"),
FAILED_DEPENDENCY(424, "Failed Dependency"),
TOO_EARLY(425, "Too Early"),
UPGRADE_REQUIRED(426, "Upgrade Required"),
PRECONDITION_REQUIRED(428, "Precondition Required"),
TOO_MANY_REQUESTS(429, "Too Many Requests"),
REQUEST_HEADER_FIELDS_TOO_LARGE(431, "Request Header Fields Too Large"),
UNAVAILABLE_FOR_LEGAL_REASONS(451, "Unavailable For Legal Reasons"),
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
NOT_IMPLEMENTED(501, "Not Implemented"),
BAD_GATEWAY(502, "Bad Gateway"),
SERVICE_UNAVAILABLE(503, "Service Unavailable"),
GATEWAY_TIMEOUT(504, "Gateway Timeout"),
HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version not supported"),
VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates"),
INSUFFICIENT_STORAGE(507, "Insufficient Storage"),
LOOP_DETECTED(508, "Loop Detected"),
BANDWIDTH_LIMIT_EXCEEDED(509, "Bandwidth Limit Exceeded"),
NOT_EXTENDED(510, "Not Extended"),
NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");
基于此,我们可以仿照jdk中的一些设计模式来设计一套更加完美的全局异常。
|