前言
在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; } }
文章评论