[java]SpringBoot实现全局异常处理

2021-03-16 1019点热度 0人点赞 0条评论

前言

在SpringBoot项目中,希望在遇到异常时(比如404,或者代码中抛出的未知错误),能统一返回规定的格式(例如返回JSON格式的异常报错{"result": false, "message": "NullPonterException ..."}),而不是希望在所有的逻辑处理上加上监测异常。

实现

application.properties下增加如下:

server.error.whitelabel.enabled=false
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

新增GlobalExceptionHandler.java

我这里的实例是全局异常处理,返回JSON格式的错误输出。

package com.terrynow.test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Terry E-mail: yaoxinghuo at 126 dot com
 *
 * application.properties需要加:
 * server.error.whitelabel.enabled=false
 * spring.mvc.throw-exception-if-no-handler-found=true
 * spring.resources.add-mappings=false
 *
 * @EnableWebMvc 加上以后发现首页/直接输出html会报500错误
 */
//@EnableWebMvc
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    private static Log log = LogFactory.getLog(GlobalExceptionHandler.class);

    // 处理404
    @Override
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
                                                                   HttpStatus status, WebRequest request) {
//        response.setStatus(httpStatus.value());
        log.warn("request no handler found for: " + request.getDescription(true));
        Map<String, Object> responseBody = new HashMap<>();
        responseBody.put("result", false);
        responseBody.put("path", request.getDescription(true));
        responseBody.put("time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        responseBody.put("message", "The URL you have reached is not in service at this time (404).");
        return new ResponseEntity<>(responseBody, HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(Throwable.class)
    public ModelAndView exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        //If exception has a ResponseStatus annotation then use its response code
        ResponseStatus responseStatusAnnotation = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);

        return buildModelAndViewErrorPage(request, response, ex, responseStatusAnnotation != null ?
                responseStatusAnnotation.value() : HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @RequestMapping("*")
    public ModelAndView fallbackHandler(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return buildModelAndViewErrorPage(request, response, null, HttpStatus.NOT_FOUND);
    }

    private ModelAndView buildModelAndViewErrorPage(HttpServletRequest request, HttpServletResponse response,
                                                    Exception ex, HttpStatus httpStatus) {
        log.error("request handle error for: " + request.getRequestURI() + ", status: " + httpStatus.value(), ex);
        String exMessage = ex.getMessage();
//        if (ex != null && exMessage.startsWith("410 ")) {
//            try {
//                response.sendError(410, ex.getMessage());
//            } catch (IOException e) {
//            }
//        }

//        ModelAndView mav = new ModelAndView("error.html");
//        if (ex != null) {
//            mav.addObject("title", ex);
//        }
//        mav.addObject("content", request.getRequestURL());
//        return mav;
        return buildErrorView(httpStatus, request.getRequestURI(), "Exception: " + exMessage);
    }

    public static ModelAndView buildErrorView(HttpStatus status, String path, String message) {
        ModelAndView model = new ModelAndView();
        model.setView(new MappingJackson2JsonView());
        model.addObject("result", false);
        model.addObject("path", path);
        model.addObject("time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        model.addObject("message", message);
        model.setStatus(status);
        return model;
    }
}

 

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论