package com.kiisoo.ic.config; import com.kiisoo.ic.common.BaseController; import org.apache.shiro.ShiroException; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.UnauthenticatedException; import org.apache.shiro.authz.UnauthorizedException; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.NoHandlerFoundException; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 异常控制处理器 * * @author z */ @RestControllerAdvice public class ExceptionAdvice extends BaseController { /** * 捕捉所有Shiro异常 * * @param e * @return */ @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(ShiroException.class) public Map handle401(ShiroException e) { return fail(HttpStatus.UNAUTHORIZED.value() + "", e.getMessage()); } /** * 单独捕捉Shiro(UnauthorizedException)异常 * 该异常为访问有权限管控的请求而该用户没有所需权限所抛出的异常 * * @param e * @return */ @ResponseStatus(HttpStatus.FORBIDDEN) @ExceptionHandler({UnauthorizedException.class, AuthorizationException.class}) public Map handle401(UnauthorizedException e) { return fail("40001", e.getMessage()); } /** * 单独捕捉Shiro(UnauthenticatedException)异常 * 该异常为以游客身份访问有权限管控的请求无法对匿名主体进行授权,而授权失败所抛出的异常 * * @param e * @return */ @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(UnauthenticatedException.class) public Map handle401(UnauthenticatedException e) { return fail("40001", "认证异常: " + e.getMessage()); } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(BindException.class) public Map validException(BindException e) { List fieldErrors = e.getBindingResult().getFieldErrors(); Map result = this.getValidError(fieldErrors); return fail("40006", result); } /** * 捕捉校验异常(MethodArgumentNotValidException) * * @return */ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(MethodArgumentNotValidException.class) public Map validException(MethodArgumentNotValidException e) { List fieldErrors = e.getBindingResult().getFieldErrors(); Map result = this.getValidError(fieldErrors); return fail("406", result.get("errorList")); } /** * 捕捉404异常 * * @return */ @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(NoHandlerFoundException.class) public Map handle(NoHandlerFoundException e) { return fail("404", "资源不存在"); } @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(HttpMessageNotReadableException.class) public Map httpMessageNotReadableException(HttpServletRequest request, Throwable ex) { return fail(this.getStatus(request).value() + "", "请求参数错误"); } /** * 捕捉其他所有异常 * * @param request * @param ex * @return */ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(Exception.class) public Map globalException(HttpServletRequest request, Throwable ex) { ex.printStackTrace(); return fail(this.getStatus(request).value() + "", ex.toString() + ": " + ex.getMessage()); } /** * 获取状态码 * * @param request * @return */ private HttpStatus getStatus(HttpServletRequest request) { Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); if (statusCode == null) { return HttpStatus.INTERNAL_SERVER_ERROR; } return HttpStatus.valueOf(statusCode); } /** * 获取校验错误信息 * * @param fieldErrors * @return */ private Map getValidError(List fieldErrors) { Map result = new HashMap(16); List errorList = new ArrayList(); StringBuffer errorMsg = new StringBuffer(); for (FieldError error : fieldErrors) { errorList.add(error.getDefaultMessage()); errorMsg.append(error.getDefaultMessage()); } result.put("errorList", errorList); result.put("errorMsg", errorMsg); return result; } }