工作时候使用到的异常统一处理,在此记录一下。按照步骤来,即可
如果直接把异常打印给前台,一个是前台看不懂,更主要没什么意义,还显得很low
第一步引入jar包
二定义一个错误信息类
public class Result
// error_code0 成功,其他 失败
private Integer status;
// error_msg 错误信息
private String msg;
// content 返回体报文的出参,使用泛型兼容不同的类型
private T data;
public Integer getStatus() {
return status;
}
public void setStatus(Integer code) {
this.status = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData(Object object) {
return data;
}
public void setData(T data) {
this.data = data;
}
public T getData() {
return data;
}
@Override
public String toString() {
return "Result{" +
"status=" + status +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
第三步错误信息枚举
public enum ExceptionEnum {
UNKNOW_ERROR(-1,"未知错误"),
USER_NOT_FIND(-101,"用户不存在"),
;
private Integer code;
private String msg;
ExceptionEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
第四部返回信息工具类
public class ResultUtil {
/**
* 返回成功,传入返回体具体出參
* @param object
* @return
*/
public static Result success(Object object){
Result result = new Result();
result.setStatus(0);
result.setMsg("success");
result.setData(object);
return result;
}
/**
* 提供给部分不需要出參的接口
* @return
*/
public static Result success(){
return success(null);
}
/**
* 自定义错误信息
* @param code
* @param msg
* @return
*/
public static Result error(Integer code,String msg){
Result result = new Result();
result.setStatus(code);
result.setMsg(msg);
result.setData(null);
return result;
}
/**
* 返回异常信息,在已知的范围内
* @param exceptionEnum
* @return
*/
public static Result error(ExceptionEnum exceptionEnum){
Result result = new Result();
result.setStatus(exceptionEnum.getCode());
result.setMsg(exceptionEnum.getMsg());
result.setData(null);
return result;
}
}
第六步自定义异常
public class DescribeException extends RuntimeException{
private Integer code;
/**
* 继承exception,加入错误状态值
* @param exceptionEnum
*/
public DescribeException(ExceptionEnum exceptionEnum) {
super(exceptionEnum.getMsg());
this.code = exceptionEnum.getCode();
}
/**
* 自定义错误信息
* @param message
* @param code
*/
public DescribeException(String message, Integer code) {
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
第七步异常信息处理
@ControllerAdvice
public class ExceptionHandle {
private final static Logger LOGGER = LoggerFactory.getLogger(ExceptionHandle.class);
/**
* 判断错误是否是已定义的已知错误,不是则由未知错误代替,同时记录在log中
* @param e
* @return
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result exceptionGet(Exception e){
if(e instanceof DescribeException){
DescribeException MyException = (DescribeException) e;
return ResultUtil.error(MyException.getCode(),MyException.getMessage());
}
LOGGER.error("【系统异常】{}",e);
return ResultUtil.error(ExceptionEnum.UNKNOW_ERROR);
}
}
我们使用了 @ControllerAdvice ,使Spring能加载该类,同时我们将所有捕获的异常统一返回结果Result这个实体。
第八部添加切面
@Aspect
@Component
public class HttpAspect {
private final static Logger LOGGER = LoggerFactory.getLogger(HttpAspect.class);
@Autowired
private ExceptionHandle exceptionHandle;
@Pointcut("execution(public * com.zzp.controller.*.*(..))")
public void log(){
}
@Before("log()")
public void doBefore(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//url
LOGGER.info("url={}",request.getRequestURL());
//method
LOGGER.info("method={}",request.getMethod());
//ip
LOGGER.info("id={}",request.getRemoteAddr());
//class_method
LOGGER.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
//args[]
LOGGER.info("args={}",joinPoint.getArgs());
}
@Around("log()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Result result = null;
try {
} catch (Exception e) {
return exceptionHandle.exceptionGet(e);
}
if(result == null){
return proceedingJoinPoint.proceed();
}else {
return result;
}
}
@AfterReturning(pointcut = "log()",returning = "object")//打印输出结果
public void doAfterReturing(Object object){
LOGGER.info("response={}",object.toString());
}
}
测试
@RestController
@RequestMapping("/result")
public class ResultController {
@Autowired
private ExceptionHandle exceptionHandle;
/**
* 返回体测试
* @param name
* @param pwd
* @return
*/
@RequestMapping(value = "/getResult",method = RequestMethod.POST)
public Result getResult(@RequestParam("name") String name, @RequestParam("pwd") String pwd){
Result result = ResultUtil.success();
try {
if (name.equals("zzp")){
result = ResultUtil.success(new UserInfo());
}else if (name.equals("pzz")){
result = ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
}else{
int i = 1/0;
}
}catch (Exception e){
result = exceptionHandle.exceptionGet(e);
}
return result;
}
}
閱讀更多 有志者1281 的文章