Global exception handling at work
1. Exception enumeration (ErrorEnum), used to store, unique code identification, exception code, exception information
import lombok.Getter;
import org.springframework.http.HttpStatus;
@Getter
public enum ErrorEnum {
RESOURCE_NOT_FOUND(1000,HttpStatus.NOT_FOUND,"没找到资源"),
URL_TOO_LONG(1001,HttpStatus.URI_TOO_LONG,"你这写这么长干嘛")
;
private final int code;
private final HttpStatus status;
private final String message;
ErrorEnum(int code, HttpStatus status, String message) {
this.code = code;
this.status = status;
this.message = message;
}
}
2. Basic exception class (BaseEception), save exception enumeration, return error data
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.util.ObjectUtils;
import java.util.HashMap;
@Setter
@Getter
@ToString
public class BaseException extends RuntimeException{
private final ErrorEnum error;
private final HashMap<String,Object> data = new HashMap<>();
public BaseException(ErrorEnum error,HashMap<String,Object> data) {
super(error.getMessage());
this.error = error;
//这里不能用!data.isEmpty(),因为如果是null,就会报空指针异常
if(!ObjectUtils.isEmpty(data)){
this.data.putAll(data);
}
}
}
3. The exception object (ErrorResult) returned to the client, enumerating unique identifier, status code, exception information, request path, and timestamp
@Setter
@Getter
@ToString
//这里lombok注解不能少,没安装插件就自己加上
public class ErrorResult {
private int code;
private HttpStatus status;
private String message;
private String path;
private Instant timestamp;
private HashMap<String, Object> data = new HashMap<String, Object>();
public ErrorResult(int code, int status, String message, String path, Instant timestamp, HashMap<String, Object> data) {
this.code = code;
this.message = message;
this.path = path;
this.timestamp = timestamp;
//这里不能用!data.isEmpty(),因为如果是null,就会报空指针异常
if(!ObjectUtils.isEmpty(data)){
this.data = data;
}
}
public ErrorResult(BaseException ex,String path) {
this.code = ex.getError().getCode();
this.status = ex.getError().getStatus();
this.message = ex.getError().getMessage();
this.path = path;
this.timestamp = Instant.now();
this.data = ex.getData();
}
}
4. Custom exception handling class, inherit the basic exception class (BaseEception)
public class ResourceNotFoundException extends BaseException{
public ResourceNotFoundException( HashMap<String, Object> data) {
super(ErrorEnum.RESOURCE_NOT_FOUND, data);
}
public ResourceNotFoundException() {
super(ErrorEnum.RESOURCE_NOT_FOUND, null);
}
}
5. Global exception capture (GlobalExceptionHandler), using @ControllerAdvice annotation (class) and @ExceptionHandler annotation (method)
//@ControllerAdvice(assignableTypes = {HelloWorldControler.class})这里assignableTypes指定处理哪个类的异常,不写代表全局处理
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
//ExceptionHandler()参数代表要处理的异常,可以写RuntimeException,多个ExceptionHandler会按照最优选执行,最小匹配
@ExceptionHandler(BaseException.class)
public ResponseEntity handleException(BaseException ex, HttpServletRequest request){
ErrorResult result = new ErrorResult(ex, request.getRequestURI());
return new ResponseEntity(result,new HttpHeaders(),ex.getError().getStatus());
}
}
6. Throw an exception to try the effect
@RestController
@RequestMapping("zhou_run")
public class HelloWorldControler {
@RequestMapping(value = "exception",method = RequestMethod.GET)
public void throwExce(){
HashMap<String, Object> put = new HashMap<>();
put.put("哦豁", "完蛋");
throw new ResourceNotFoundException(put);
}
}
7. Effect picture, no picture, no truth