统一异常处理
统一异常处理类
import com.honghe.managerTool.config.exception.MySecurityException;import com.honghe.managerTool.entity.Result;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;/*** @ControllerAdvice //处理所有* @ControllerAdvice(annotations=RestController.class) //处理这个类下的异常* @ControllerAdvice(basePackages={"com.honghe.managerTool.controller"}) //处理包下的异常*/@ControllerAdvicepublic class GlobalExceptionHandler {private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** //处理需要处理的异常类* @ExceptionHandler(value={RuntimeException.class,MyRuntimeException.class})* @ExceptionHandler //处理所有异常* @ExceptionHandler(MySecurityException.class) //处理专门的异常*/@ResponseBody//返回字符串@ExceptionHandlerpublic Result exceptionHandler(Exception e) {if (e instanceof MySecurityException){MySecurityException me = (MySecurityException)e;//logger.error("权限异常",e);return new Result(me.getCode(),false,e.getMessage());}else if (e instanceof NullPointerException){logger.error("空指针异常",e);return new Result(-3,false,"空指针异常");}else{return new Result(-3,false,"异常");}}}
2.
自定义异常类
/*** 权限验证异常* @author zhaojianyu*/public class MySecurityException extends RuntimeException {private Integer code;/*** 无参构造方法*/public MySecurityException(){super();}/*** 有参的构造方法*/public MySecurityException(String message,Integer code){super(message);this.code = code;}/*** 用指定的详细信息和原因构造一个新的异常*/public MySecurityException(String message, Throwable cause){super(message,cause);}/*** 用指定原因构造一个新的异常*/public MySecurityException(Throwable cause) {super(cause);}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}}
抛出自定义异常
throw new MySecurityException("请求超时,请同步服务器时间",-2);
返回值代码枚举类
/**** 返回值枚举类* @author: zhaojianyu* @create: 2018-10-11 17:50**/public enum ResultEnum {/*** 异常信息*/UNKONW_ERROR(-1,"未知错误"),SUCCESS(0,"请求成功"),SECURITY_EXCEPTION(-2,"权限异常"),PARAMS_EXCEPTION(-3,"权限异常");private Integer code;private String message;ResultEnum() {}ResultEnum(Integer code, String message) {this.code = code;this.message = message;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}}
统一处理校验异常
针对参数校验 会发生以下三种异常
@RequestBody可以标注在实体上 校验失败抛出异常:MethodArgumentNotValidException@PathVariable以及@RequestParam时 直接标注在方法参数上,同时需要在controller类上加上@Validated进行标注 校验失败抛出异常:ConstraintViolationException- 当get请求中 参数为实体时, 校验失败会抛出
BindException
import com.tinet.smartlink.commons.mvc.response.ApiResponseEntity;import com.tinet.smartlink.commons.mvc.response.ErrorCode;import lombok.extern.slf4j.Slf4j;import org.springframework.http.ResponseEntity;import org.springframework.validation.BindException;import org.springframework.validation.BindingResult;import org.springframework.validation.FieldError;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestControllerAdvice;import org.springframework.web.context.request.WebRequest;import javax.validation.ConstraintViolationException;import java.util.*;/*** 统一异常处理* @author zhaojy*/@Slf4j@RestControllerAdvicepublic class GlobalExceptionHandler {/*** 参数校验统一异常处理*/@ResponseBody@ExceptionHandler(value = {ConstraintViolationException.class, MethodArgumentNotValidException.class, BindException.class})public ResponseEntity<Object> handleMethodArgumentException(Exception e, WebRequest request) {StringBuilder message = new StringBuilder("[参数校验失败]: ");Map<String, Object> map = null;if (e instanceof MethodArgumentNotValidException) {BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();message.append(getExceptionMessageMap(bindingResult));} else if (e instanceof ConstraintViolationException) {message.append(e.getMessage());} else if (e instanceof BindException) {message.append(getExceptionMessageMap((BindingResult) e));}log.warn(message.toString());return ApiResponseEntity.error(ErrorCode.InvalidParameter, message.toString()).toResponseEntity();}/*** 获取校验失败字段 及message** @param bindingResult 结果* @return 空map 或 错误信息map*/private Map<String, Object> getExceptionMessageMap(BindingResult bindingResult) {Map<String, Object> map;if (Objects.isNull(bindingResult)){return new HashMap<>(1);}if (bindingResult.hasErrors()) {List<FieldError> fieldErrors = bindingResult.getFieldErrors();map = new HashMap<>(fieldErrors.size());fieldErrors.forEach(error -> map.put(error.getField(), error.getDefaultMessage()));} else {map = new HashMap<>(1);}return map;}}
