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