package com.izouma.nineth.exception; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.transaction.TransactionSystemException; import org.springframework.validation.BindException; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; 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 org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.Path; import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import java.util.stream.Collectors; @ControllerAdvice @Slf4j public class GlobalExceptionHandler { @ExceptionHandler(value = BusinessException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public Map serviceExceptionHandler(BusinessException e) { Map map = new HashMap<>(); map.put("error", e.getMessage()); map.put("code", -1); return map; } @ExceptionHandler({AuthenticationException.class}) @ResponseStatus(HttpStatus.UNAUTHORIZED) @ResponseBody public Map handleAuthenticationException(AuthenticationException e) { Map map = new HashMap<>(); map.put("error", e.getMessage()); map.put("code", -1); return map; } @ExceptionHandler(value = TransactionSystemException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public Map serviceExceptionHandler(TransactionSystemException e) { String message = e.getMessage(); try { if (e.getCause().getCause() instanceof ConstraintViolationException) { ConstraintViolationException violationException = (ConstraintViolationException) e.getCause() .getCause(); message = violationException.getConstraintViolations().stream() .map(constraintViolation -> constraintViolation.getPropertyPath() + constraintViolation.getMessage()) .collect(Collectors.joining(",")); log.error(message); } } catch (Exception ignore) { } Map map = new HashMap<>(); map.put("error", message); map.put("code", -1); return map; } @ExceptionHandler(value = Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public Object serviceExceptionHandler(Exception e, HttpServletRequest request) { log.error(e.getMessage(), e); if (request.getHeader("Accept").contains("text/html")) { ModelAndView modelAndView = new ModelAndView("commons/500"); StringWriter out = new StringWriter(); PrintWriter writer = new PrintWriter(out); e.printStackTrace(writer); String trace = out.toString(); trace = trace.replaceAll("\n", "
"); modelAndView.addObject("trace", trace); return modelAndView; } else { String message = e.getMessage(); if (Pattern.matches(".*SQL.*constraint.*user_index_phone.*", e.getMessage())) { message = "手机号已注册"; } if (Pattern.matches(".*SQL.*constraint.*username.*", e.getMessage())) { message = "用户名已存在"; } Map map = new HashMap<>(); map.put("error", message); map.put("code", -1); return map; } } @ExceptionHandler({BindException.class, ConstraintViolationException.class, MethodArgumentNotValidException.class}) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public Map validateExceptionHandler(Exception e, HttpServletRequest request) { log.error("请求:{}发生异常:{}", request.getRequestURI(), e); // 错误信息 StringBuilder sb = new StringBuilder("参数校验失败:"); // 错误信息map Map error = new HashMap<>(); String msg = ""; if (!(e instanceof BindException) && !(e instanceof MethodArgumentNotValidException)) { for (ConstraintViolation cv : ((ConstraintViolationException) e).getConstraintViolations()) { msg = cv.getMessage(); sb.append(msg).append(";"); Iterator it = cv.getPropertyPath().iterator(); Path.Node last = null; while (it.hasNext()) { last = (Path.Node) it.next(); } /*for(last = null; it.hasNext(); last = (Path.Node)it.next()) { }*/ error.put(last != null ? last.getName() : "", msg); } } else { List allErrors = null; if (e instanceof BindException) { allErrors = ((BindException) e).getAllErrors(); } else { allErrors = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors(); } // 拼接错误信息 for (ObjectError oe : allErrors) { msg = oe.getDefaultMessage(); sb.append(msg).append(";"); if (oe instanceof FieldError) { error.put(((FieldError) oe).getField(), msg); } else { error.put(oe.getObjectName(), msg); } } } Map map = new HashMap<>(); map.put("error", "参数校验失败"); map.put("message", sb); map.put("code", -1); log.error(e.getMessage()); return map; } }