<返回更多

如何使用 Spring Boot 实现异常处理

2023-04-06  今日头条  inkfoxer
加入收藏

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

 

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>