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

2021-03-16 1521点热度 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
server.error.whitelabel.enabled=false spring.mvc.throw-exception-if-no-handler-found=true spring.resources.add-mappings=false
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;
}
}
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; } }
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

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

文章评论

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