采用@ControllerAdvice+@ExceptionHandler方式的全局的异常处理
1.先定义一个全局的异常类,继承Exception ,里面有code属性,表示请求的响应状态码。
/**
* @ClassName GlobalException
* @Description 全局异常
**/
public class GlobalException extends Exception implements java.io.Serializable{
private int code;
public void setCode(int code) {
this.code = code;
}
public int getCode() {
retun code;
}
public GlobalException(GlobalException e) {
super(e.getMessage());
this.code = e.getCode();
}
public GlobalException(String message) {
super(message);
}
public GlobalException(String message, int code) {
super(message);
this.code = code;
}
}
2.定义一个全局异常处理Handler类,使用自己的统一返回类返回
import com.sany.customException.GlobalException;
import com.sany.utils.ResultVoUtil;
import com.sany.vo.ResultVo;
import org.springframework.validation.FieldError;
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.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 参数校验统一返回
* @param e
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResultVo handler(MethodArgumentNotValidException e){
//简化错误提示
StringBuffer msg = new StringBuffer();
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
for (FieldError fieldError : fieldErrors) {
msg.append(fieldError.getDefaultMessage()+" ");
}
return ResultVoUtil.error(e.hashCode(),msg.toString(),null);
}
/**
* 自定义异常处理 一个Controller下多个@ExceptionHandler上的异常类型不能出现一样的,否则运行时抛异常.
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(GlobalException.class)
@ResponseBody
public ResultVo jsonErrorHandler(HttpServletRequest req, GlobalException e) throws Exception {
ResultVo r = new ResultVo();
r.setMsg(e.getMessage());
r.setCode(e.getCode());
r.setData(null);
return r;
}
/**
* 系统异常处理
* @param req
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResultVo defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
ResultVo r = new ResultVo();
r.setMsg(e.getMessage());
r.setCode(e.hashCode());
r.setData(null);
return r;
}
}
3.通常情况下,全局Handler我们会放在公共模块,子服务启动加载时可能加载不到。最简单的方法是在启动类使用@ComponentScan指定包名(别忘记添加启动类路径,这个注解扫描时自己的项目就不会被扫描到,所以要把自己项目的包路径写进来所以上面扫描了两个路径。)