spring boot GlobalExceptionHandler @RestControllerAdvice @ExceptionHandler

Posted tonggc1668

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot GlobalExceptionHandler @RestControllerAdvice @ExceptionHandler相关的知识,希望对你有一定的参考价值。

package me.zhengjie.common.exception.handler;

import lombok.extern.slf4j.Slf4j;
import me.zhengjie.common.exception.BadRequestException;
import me.zhengjie.common.exception.EntityExistException;
import me.zhengjie.common.exception.EntityNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.io.PrintWriter;
import java.io.StringWriter;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;

/**
 * @author jie
 * @date 2018-11-23
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler 

    /**
     * 处理所有不可知的异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity handleException(Exception e)
        // 打印堆栈信息
        log.error(getStackTrace(e));
        ApiError apiError = new ApiError(BAD_REQUEST.value(),e.getMessage());
        return buildResponseEntity(apiError);
    

    /**
     * 处理 接口无权访问异常AccessDeniedException
     * @param e
     * @return
     */
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseEntity handleAccessDeniedException(AccessDeniedException e)
        // 打印堆栈信息
        log.error(getStackTrace(e));
        ApiError apiError = new ApiError(FORBIDDEN.value(),e.getMessage());
        return buildResponseEntity(apiError);
    

    /**
     * 处理自定义异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = BadRequestException.class)
    public ResponseEntity<ApiError> badRequestException(BadRequestException e) 
        // 打印堆栈信息
        log.error(getStackTrace(e));
        ApiError apiError = new ApiError(e.getStatus(),e.getMessage());
        return buildResponseEntity(apiError);
    

    /**
     * 处理 EntityExist
     * @param e
     * @return
     */
    @ExceptionHandler(value = EntityExistException.class)
    public ResponseEntity<ApiError> entityExistException(EntityExistException e) 
        // 打印堆栈信息
        log.error(getStackTrace(e));
        ApiError apiError = new ApiError(BAD_REQUEST.value(),e.getMessage());
        return buildResponseEntity(apiError);
    

    /**
     * 处理 EntityNotFound
     * @param e
     * @return
     */
    @ExceptionHandler(value = EntityNotFoundException.class)
    public ResponseEntity<ApiError> entityNotFoundException(EntityNotFoundException e) 
        // 打印堆栈信息
        log.error(getStackTrace(e));
        ApiError apiError = new ApiError(NOT_FOUND.value(),e.getMessage());
        return buildResponseEntity(apiError);
    

    /**
     * 处理所有接口数据验证异常
     * @param e
     * @returns
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ApiError> handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
        // 打印堆栈信息
        log.error(getStackTrace(e));
        String[] str = e.getBindingResult().getAllErrors().get(0).getCodes()[1].split("\\.");
        StringBuffer msg = new StringBuffer(str[1]+":");
        msg.append(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        ApiError apiError = new ApiError(BAD_REQUEST.value(),msg.toString());
        return buildResponseEntity(apiError);
    

    /**
     * 统一返回
     * @param apiError
     * @return
     */
    private ResponseEntity<ApiError> buildResponseEntity(ApiError apiError) 
        return new ResponseEntity(apiError, HttpStatus.valueOf(apiError.getStatus()));
    

    /**
     * 获取堆栈信息
     * @param throwable
     * @return
     */
    private String getStackTrace(Throwable throwable)
    
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        try 
            throwable.printStackTrace(pw);
            return "\n"+sw.toString();
         finally 
            pw.close();
        
    
package me.zhengjie.common.exception.handler;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;

/**
 * @author jie
 * @date 2018-11-23
 */
@Data
class ApiError 

    private Integer status;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime timestamp;
    private String message;

    private ApiError() 
        timestamp = LocalDateTime.now();
    

    public ApiError(Integer status,String message) 
        this();
        this.status = status;
        this.message = message;
    

 

以上是关于spring boot GlobalExceptionHandler @RestControllerAdvice @ExceptionHandler的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

spring-boot-quartz, 依赖spring-boot-parent

spring-boot系列:初试spring-boot

Spring-Boot Banner

Spring Boot:Spring Boot启动原理分析