在Spring Boot中,可以使用@ControllerAdvice注解來實現全局異常處理。以下是具體的代碼實現:
package com.myfunnel.exceptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Object> handleException(Exception e) {
logger.error("Exception caught: {}", e.getMessage(), e);
return new ResponseEntity<>("An error occurred: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(value = IllegalArgumentException.class)
public ResponseEntity<Object> handleIllegalArgumentException(IllegalArgumentException e) {
logger.error("IllegalArgumentException caught: {}", e.getMessage(), e);
return new ResponseEntity<>("Invalid argument: " + e.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(value = EntityNotFoundException.class)
public ResponseEntity<Object> handleEntityNotFoundException(EntityNotFoundException e) {
logger.error("EntityNotFoundException caught: {}", e.getMessage(), e);
return new ResponseEntity<>("Entity not found: " + e.getMessage(), HttpStatus.NOT_FOUND);
}
}
上面的代碼示例中,出現任何異常時,都會進入handleException方法,并返回500的響應碼。如果拋出IllegalArgumentException異常,則進入handleIllegalArgumentException方法,返回400響應碼。如果出現EntityNotFoundException異常,則進入handleEntityNotFoundException方法,返回404響應碼。
需要注意的是,如果@ExceptionHandler注解標注的方法沒有被調用,則需要檢查是否適當配置了ControllerAdvice。配合@RestControllerAdvice注解更佳。
如果需要定制化異常,則可以自定義異常類,并在其中定義需要返回的響應碼和響應信息等。例如:
package com.myfunnel.exceptions;
/**
* @Description
* @Author shenshixi
* @Date 2022/6/14 23:42
* @Version 1.0
*/
public class MyException extends RuntimeException{
private int code;
private String message;
public MyException(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
EntityNotFoundException異常以下是一個可能的實現:
package com.myfunnel.exceptions;
public class EntityNotFoundException extends RuntimeException{
/**
* Constructs a new runtime exception with the specified detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public EntityNotFoundException(String message) {
super(message);
}
}
使用時,可以在具體的方法中拋出MyException異常:
@GetMApping("/api/v1/users/{id}")
public ResponseEntity<User> getUser(@PathVariable long id) {
User user = userService.getUserById(id);
if (user == null) {
throw new MyException(404, "User not found with id: " + id);
}
return ResponseEntity.ok(user);
}
然后,需要在GlobalExceptionHandler中添加MyException的處理方法:
復制@ExceptionHandler(value = MyException.class)
public ResponseEntity<Object> handleMyException(MyException e) {
logger.error("MyException caught: {}", e.getMessage(), e);
return new ResponseEntity<>(e.getMessage(), HttpStatus.valueOf(e.getCode()));
}
這樣,當出現MyException異常時,就會進入handleMyException方法,并返回自定義的響應信息和響應碼。