统一异常处理
统一异常处理类
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"}) //处理包下的异常
*/
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* //处理需要处理的异常类
* @ExceptionHandler(value={RuntimeException.class,MyRuntimeException.class})
* @ExceptionHandler //处理所有异常
* @ExceptionHandler(MySecurityException.class) //处理专门的异常
*/
@ResponseBody//返回字符串
@ExceptionHandler
public 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
@RestControllerAdvice
public 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;
}
}