经常要处理一些controller报出来的异常 ,以免报错到前端页面形成不好的用户体验。
一个个处理很繁琐,容易漏掉,而且很不优雅。最近发现可以用全局异常来处理。非常的方便,而且有个好处就是返回的样式很统一。
在异常处理中主要运用了spring的注解@ControllerAdvice
效果是这样的滴。
下面上代码
全局异常处理类
package com.pobo.liang.ws.exceptionHandler; import com.pobo.liang.ws.model.Result; import com.pobo.liang.ws.utils.ExceptionUtil; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.ExpiredCredentialsException; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.LockedAccountException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.TypeMismatchException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.NoHandlerFoundException; import javax.servlet.http.HttpServletRequest; import javax.validation.ValidationException; /** * 异常处理 */ @RestController @CrossOrigin @ControllerAdvice class GlobalExceptionHandler { private Logger logger = LoggerFactory.getLogger(this.getClass()); private HttpServletRequest req; private HttpRequestMethodNotSupportedException e; @ExceptionHandler(value = Exception.class) @ResponseBody Object exception(HttpServletRequest req, Exception e) { e.printStackTrace(); logger.error("系统错误: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(500, "系统错误"); } @ExceptionHandler(value = IllegalArgumentException.class) @ResponseBody Object exception(HttpServletRequest req, IllegalArgumentException e) { e.printStackTrace(); logger.error("Assert错误: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(1000, e.getMessage()); } @ExceptionHandler(value = NoHandlerFoundException.class) @ResponseBody Object noHandlerFoundException(HttpServletRequest req, NoHandlerFoundException e) { logger.error("找不到请求路径: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(404, e.getLocalizedMessage()); } @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class) @ResponseBody Object httpRequestMethodNotSupportedException(HttpServletRequest req, HttpRequestMethodNotSupportedException e) { logger.error("请求method不支持: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(400, e.getLocalizedMessage()); } @ExceptionHandler(value = TypeMismatchException.class) @ResponseBody Object TypeMismatchException(HttpServletRequest req, TypeMismatchException e) { logger.error("缺少请求参数: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(400, e.getLocalizedMessage()); } @ExceptionHandler(value = ValidationException.class) @ResponseBody Object ValidationException(HttpServletRequest req, ValidationException e) { logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(400, e.getLocalizedMessage()); } @ExceptionHandler(value = MissingPathVariableException.class) @ResponseBody Object MissingPathVariableException(HttpServletRequest req, MissingPathVariableException e) { logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(400, e.getLocalizedMessage()); } @ExceptionHandler(value = MethodArgumentNotValidException.class) @ResponseBody Object MethodArgumentNotValidException(HttpServletRequest req, MethodArgumentNotValidException e) { logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(400, e.getLocalizedMessage()); } @ExceptionHandler(value = UnsatisfiedServletRequestParameterException.class) @ResponseBody Object UnsatisfiedServletRequestParameterException(HttpServletRequest req, UnsatisfiedServletRequestParameterException e) { logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(400, e.getLocalizedMessage()); } @ExceptionHandler(value = ServletRequestBindingException.class) @ResponseBody Object ServletRequestBindingException(HttpServletRequest req, ServletRequestBindingException e) { logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(400, e.getLocalizedMessage()); } @ExceptionHandler(value = MissingServletRequestParameterException.class) @ResponseBody Object MissingServletRequestParameterException(HttpServletRequest req, MissingServletRequestParameterException e) { logger.error("参数验证失败: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(400, e.getLocalizedMessage()); } @ExceptionHandler(value = IncorrectCredentialsException.class) @ResponseBody Object incorrectCredentialsException(HttpServletRequest req, IncorrectCredentialsException e) { logger.error("用户名或密码错误: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(405, "用户名或密码错误"); } @ExceptionHandler(value = LockedAccountException.class) @ResponseBody Object lockedAccountException(HttpServletRequest req, LockedAccountException e) { logger.error("登录失败,该用户已被冻结: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(405, "登录失败,该用户已被冻结"); } @ExceptionHandler(value = AuthenticationException.class) @ResponseBody Object authenticationException(HttpServletRequest req, AuthenticationException e) { logger.error("用户名或密码错误: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(405, "用户名或密码错误"); } @ExceptionHandler(value = ExpiredCredentialsException.class) @ResponseBody Object expiredCredentialsException(HttpServletRequest req, ExpiredCredentialsException e) { logger.error("token已过期: [{}]", ExceptionUtil.getExceptionStackTrace(e)); return Result.ofFailure(405, "token已过期"); } }
返回类型的实体类:
package com.pobo.liang.ws.model; import com.fasterxml.jackson.annotation.JsonInclude; import java.io.Serializable; public class Result<T> implements Serializable { private int errcode; private String errmsg; @JsonInclude(JsonInclude.Include.NON_NULL) private T body; public static Result ofSuccess() { return new Result(0, "success"); } public static Result ofSuccess(String msg) { return new Result(0, msg); } public static Result ofFailure(int errcode, String errmsg) { return new Result(errcode, errmsg); } public Result() { } public Result(int errcode, String errmsg) { this.errcode = errcode; this.errmsg = errmsg; } public Result(int errcode, String errmsg, T body) { this.errcode = errcode; this.errmsg = errmsg; this.body = body; } public int getErrcode() { return errcode; } public Result setErrcode(int errcode) { this.errcode = errcode; return this; } public String getErrmsg() { return errmsg; } public Result setErrmsg(String errmsg) { this.errmsg = errmsg; return this; } public Object getBody() { return body; } public Result setBody(T body) { this.body = body; return this; } }
异常工具类:
package com.pobo.liang.ws.utils; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; public class ExceptionUtil { public static String getExceptionStackTrace(Throwable throwable) { if (throwable == null) { return null; } try (StringWriter sw = new StringWriter(); PrintWriter printWriter = new PrintWriter(sw);) { throwable.printStackTrace(printWriter); printWriter.flush(); sw.flush(); return sw.toString(); } catch (IOException e) { e.printStackTrace(); } return null; } }