本文出自公衆號《愚公要移山》Springboot系列
咱們的項目一般來說都是一個比較大的項目,包含了各類各樣的服務。若是每一個服務都以不一樣的方式返回異常信息,這樣排查的時候就會比較凌亂。若是咱們定義一個標準的異常處理體系。並在全部的服務中使用。那樣開發起來就能夠快速定位。頁面也會更加的簡單和直觀。web
本文開發環境基於springboot2.4,IDE環境是IDEA。這裏從一個最簡單的異常案例。逐步過渡到徹底自定義本身的異常。spring
案例:Springboot查詢數據庫數據,發現返回的是null,就拋出異常。
OK,基於這個思想,看一下實現的思路。數據庫
這個比較簡單,代碼以下:springboot
`public class User {
private int id;
private String name;
public User() {
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
//getter和setter方法
//toString方法
}
`服務器
`@Service
public class UserService {
public User findOne(int id){
//原本應該向數據庫查詢User,可是數據庫沒有
return null;
}
}
`mvc
因爲演示的是異常的案例,所以這裏沒有真正實現數據庫的增刪改查操做。當調用findOne方法時,直接返回爲null便可。app
`@RestController
public class UserController {
@Autowired
private UserService service;
@GetMapping("/users/{id}")
public User retriveUser(@PathVariable int id)
throws UserNotFoundException {
User user= service.findOne(id);
if(user==null)
throw new UserNotFoundException("id: "+ id);
return user;
}
}
`框架
這裏自定義了一個異常UserNotFoundException,當數據庫查詢的時候一旦發現返回值爲null,就直接拋出這個異常。post
`public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message){
super(message);
System.out.println("異常信息是:"+message);
}
}
`測試
1609827005387
這時候進行測試會發現服務器代碼會報錯。咱們的資源沒有找到總不能提示服務器內部錯誤吧。如今對拋出的異常進行一個處理。
`@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message){
super(message);
System.out.println("異常信息是:"+message);
}
}
`
咱們將添加一個註釋@ResponseStatus來生成狀態:404 Not Found。固然還有其餘的狀態。這個能夠根據本身的須要去返回。咱們使用了HttpStatus.NOT_FOUND用戶訪問的時候,一旦拋出了異常就會顯示404錯誤。這個你換成其餘的狀態,還會顯示其餘的信息。
1609827261976
Spring Boot和Spring MVC框架的結合提供了錯誤處理。其內部已經自動配置一些默認異常處理。因此在開發中爲全部服務配置一致的異常消息是很重要的。
`<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.2</version>
</dependency>
`
這個類的做用是,當有異常時,咱們想要展現的信息。
`public class ExceptionResponse {
private Date timestamp;
private String message;
private String detail;
public ExceptionResponse() { }
public ExceptionResponse(Date timestamp, String message, String detail) {
this.timestamp = timestamp;
this.message = message;
this.detail = detail;
}
public Date getTimestamp() {
return timestamp;
}
public String getMessage() {
return message;
}
public String getDetail() {
return detail;
}
}
`
這裏只須要實現getter方法,setter方法就不須要。
`@ControllerAdvice
@RestController
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
//此方法主要處理全部的異常信息
@ExceptionHandler(Exception.class)
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
//當出現異常時,咱們輸出的信息,這裏被封裝在了ExceptionResponse
ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
//當頁面資源沒有找到時,拋出的異常
@ExceptionHandler(UserNotFoundException.class)
public final ResponseEntity<Object> handleUserNotFoundExceptions(UserNotFoundException ex, WebRequest request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity(exceptionResponse, HttpStatus.NOT_FOUND);
}
}
`
很簡單。裏面有不少API,能夠本身根據須要去查便可。
1609828897996
萬事大吉。趕快爲你的程序自定義一個通用的異常處理程序吧。