springboot-全局異常處理

一、定義抽象異常類


import org.springframework.http.HttpStatus;

/**
 * abstract http exception
 *
 * @author yang.liu
 */
public abstract class AbstractHttpException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    private HttpStatus httpStatus;

    public AbstractHttpException(String message) {
        super(message);
    }

    public AbstractHttpException(String message, Exception e) {
        super(message, e);
    }

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

    public void setHttpStatus(HttpStatus httpStatus) {
        this.httpStatus = httpStatus;
    }
}

二、實現類

2.1 Bad Request Exception

import org.springframework.http.HttpStatus;

/**
 * bad request exception
 *
 * @author yang.liu
 */
public class BadRequestException extends AbstractHttpException {

    public BadRequestException(String message) {
        super(message);
        setHttpStatus(HttpStatus.BAD_REQUEST);
    }

}

2.2 Not Foud Exception
import org.springframework.http.HttpStatus;

/**
 * not foud exception
 *
 * @author yang.liu
 */
public class NotFoundException extends AbstractHttpException {
    public NotFoundException(String message) {
        super(message);
        setHttpStatus(HttpStatus.NOT_FOUND);
    }
}

2.3 Server Error Exception
import org.springframework.http.HttpStatus;

/**
 * Service Error Exception
 * @author yang.liu
 */
public class ServerErrorException extends AbstractHttpException {

    public ServerErrorException(String message) {
        super(message);
        setHttpStatus(HttpStatus.INTERNAL_SERVER_ERROR);
    }

    public ServerErrorException(String message, Exception e) {
        super(message, e);
        setHttpStatus(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

三、全局異常攔截處理


import lombok.Data;

import java.sql.Timestamp;
import java.time.LocalDateTime;

/**
 * 錯誤響應
 *
 * @author yang.liu
 */
@Data
public class ErrorResponse {

    private Long timestamp;

    private Integer status;

    private String exception;

    private String message;

    public ErrorResponse(Integer status, Exception exception) {
        this(status, exception, exception.getMessage());
    }

    public ErrorResponse(Integer status, Exception exception, String message) {
        this.timestamp = Timestamp.valueOf(LocalDateTime.now()).getTime();
        this.status = status;
        this.exception = exception.getClass().getName();
        this.message = message;
    }

}


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * 全局異常處理
 *
 * @author yang.liu
 */
@Slf4j
@ControllerAdvice
public class GlobalDefaultExceptionHandler {

    /**
     * 系統異常處理
     *
     * @param req
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public ErrorResponse serverError(HttpServletRequest req, Exception e) {
        log.error("error ", e.getMessage(), e);
        return new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e);
    }

    /**
     * 處理自定義異常
     *
     * @param request
     * @param ex
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({AbstractHttpException.class})
    public ErrorResponse badRequest(HttpServletRequest request, AbstractHttpException ex) {
        //打印日誌
        log.error("bad request error", ex.getMessage(), ex);
        return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), ex);
    }

    /**
     * 參數校驗失敗
     *
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ErrorResponse methodArgumentNotValidException(HttpServletRequest req, MethodArgumentNotValidException e) {
        log.error("valid error ", e.getMessage(), e);
        BindingResult result = e.getBindingResult();
        List<String> errors = result.getFieldErrors().stream()
                .map(error -> error.getField() + ":" + error.getDefaultMessage())
                .collect(toList());
        return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e, StringUtils.join(errors, ";"));
    }

    /**
     * 參數校驗失敗
     *
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ConstraintViolationException.class)
    public ErrorResponse constraintViolationException(HttpServletRequest req, ConstraintViolationException e) {
        log.error("violation error", e);
        List<String> errors = e.getConstraintViolations().stream()
                .map(error -> error.getMessage())
                .collect(toList());
        return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e, StringUtils.join(errors, ";"));
    }

}


四、使用示例

  
    if(user == null){
        throw new BadRequestException("用戶不存在");
    }

    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章