在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方法,并返回自定义的响应信息和响应码。