1、全局异常处理
import lombok.extern.slf4j.Slf4j; import org.slf4j.helpers.MessageFormatter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; import org.springframework.validation.ObjectError; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import java.util.HashMap; import java.util.Set; import java.util.stream.Collectors; /** * 全局异常处理器 * * */ @Slf4j @ControllerAdvice public class AdminGlobalExceptionHandler { @ExceptionHandler(value = DecorateException.class) @ResponseBody public SvResult<String> decorateException(HttpServletRequest req, HttpServletResponse resp, DecorateException e) { log.error("异常消息:{}, msgVariableArr={}", e.getMessage(), e.getMsgVariableArr(), e); SvResult<String> result = new SvResult<>(e.getCode(), e.getMessage()); if(e.getMsgVariableArr() != null && i18nReplaceService != null){ result.setMsg(String.format(e.getMessage(), e.getMsgVariableArr())); result.setExt(new HashMap<>(2)); result.getExt().put(SvResultConstant.EXT_KEY_MSG_VRIABLE_ARR, e.getMsgVariableArr()); } return result; } // 处理单个参数校验失败抛出的异常 @ResponseBody @ExceptionHandler(ConstraintViolationException.class) public SvResult<String> constraintViolationExceptionHandler(ConstraintViolationException e) { log.error("[PARAM] handle param not valid exception, msg:{}", e.getMessage(), e); Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations(); String error = constraintViolations.stream() .map(ConstraintViolation::getMessage) .collect(Collectors.joining(",")); log.error("constraintViolationExceptionHandler, {}", error); return new SvResult<>(SvResultEnum.SYSTEM_ERROR); } // 处理 form 方式调用接口校验失败抛出的异常 @ResponseBody @ExceptionHandler(BindException.class) public SvResult<String> bindExceptionHandler(BindException e) { ObjectError objectError = e.getBindingResult().getAllErrors().get(0); String errorMsg = objectError.getDefaultMessage(); String field = e.getBindingResult().getFieldError().getField(); log.error("[PARAM] handle param not valid exception, field={} msg={}", field, errorMsg, e); return new SvResult<>(SvResultEnum.SYSTEM_ERROR); } // 处理 post 方式提交的 json 数据的参数验证抛出的异常 @ResponseBody @ExceptionHandler(MethodArgumentNotValidException.class) public SvResult<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) { ObjectError objectError = e.getBindingResult().getAllErrors().get(0); String errorMsg = objectError.getDefaultMessage(); String field = e.getBindingResult().getFieldError().getField(); log.error("[PARAM] handle param not valid exception, field={} msg={}", field, errorMsg, e); return new SvResult<>(SvResultEnum.SYSTEM_ERROR); } // http方法不支持的异常 @ResponseBody @ExceptionHandler(HttpRequestMethodNotSupportedException.class) public SvResult<String> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) { log.error("[SYSTEM] handle HttpRequestMethodNotSupportedException,msg: {}", exception.getMessage(), exception); String message = MessageFormatter.format("当前接口的HTTP请求不支持 {} 方法!", exception.getMethod()).getMessage(); log.error("handleHttpRequestMethodNotSupportedException {}", message); return new SvResult<>(SvResultEnum.CLIENT_ERROR); } // 兜底异常拦截 @ResponseBody @ExceptionHandler(Throwable.class) public SvResult<String> allHandler(Throwable e) { log.error("全局异常(系统异常),异常消息:{},异常类:", e.getMessage(), e); return new SvResult<>(SvResultEnum.SYSTEM_ERROR); } }
2、全局异常处理
package com.example.demo.exception; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; @Slf4j @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public Object handleException(Exception ex) { if (isJsonRequest()) { // 返回JSON格式的错误信息 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal Server Error"); } else { // 返回错误页面 ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error"); modelAndView.addObject("errorMessage", "Internal Server Error"); return modelAndView; } } private boolean isJsonRequest() { // 判断请求的Accept头部信息是否包含JSON类型 String acceptHeader = getRequest().getHeader("Accept"); log.warn("accept:"+acceptHeader); return acceptHeader != null && acceptHeader.contains(MediaType.APPLICATION_JSON_VALUE); } private HttpServletRequest getRequest() { // 获取当前请求的HttpServletRequest对象 ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); return requestAttributes.getRequest(); } }