Rest接口中,异常处理更通用。

       Java程序中,异常处理对于程序来说是非常基础。但是真正能很好理解并且很好的统一处理,这样会使得代码逻辑更清晰,更高效。下面就是程序中需要处理并且注意的异常统一处理案例:

通用异常处理类:

package com.jd.ccc.sys.biz.yb.mall.common.exception;

import com.jd.ccc.sys.biz.yb.mall.common.enums.CodeEnum;
import lombok.ToString;

/**
 * 商城通用异常
 * 
 * @create 2018-4-28
 * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
 *
 */
@ToString
public class YbMallException extends RuntimeException {

   private static final long serialVersionUID = 111820440373615072L;

   /**
    * 异常代码
    */
   private int code;
   /**
    * 异常消息
    */
   private String message;

   public YbMallException(CodeEnum codeEnum) {
      this.code = codeEnum.getCode();
      this.message = codeEnum.getMessage();
   }

   public YbMallException(int code, String message) {
      super(message);
      this.code = code;
      this.message = message;
   }

   public YbMallException(int code, String message, Throwable cause) {
      super(message, cause);
      this.code = code;
      this.message = message;
   }

   public int getCode() {
      return code;
   }

   public void setCode(int code) {
      this.code = code;
   }

   public String getMessage() {
      return message;
   }

   public void setMessage(String message) {
      this.message = message;
   }

}
服务层异常处理类: 
package com.jd.ccc.sys.biz.yb.mall.common.exception;

import com.jd.ccc.sys.biz.yb.mall.common.enums.CodeEnum;

import lombok.ToString;
/**
 * 商城服务层异常
 * 
 * @create 2018-4-28
 * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
 *
 */
@ToString
public class YbMallServiceException extends YbMallException {

   private static final long serialVersionUID = -3140415845720194815L;

   public YbMallServiceException(CodeEnum codeEnum) {
      super(codeEnum);
   }

   public YbMallServiceException(int code, String message) {
      super(code, message);
   }

   public YbMallServiceException(int code, String message, Throwable cause) {
      super(code, message, cause);
   }

}

异常处理枚举类:

package com.jd.ccc.sys.biz.yb.mall.common.enums;

/**
 * 应答码枚举类
 * 
 * @create 2018-4-28
 * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
 */
public enum CodeEnum {

   /**
    * 处理成功
    */
   SUCCESS(200, "处理成功"),
   /**
    * 入参异常
    */
   ERROR(401, "入参异常"), 
   /**
    * 保存失败
    */
   SAVE_FAIL(402, "保存失败"), 
   /**
    * 查询失败
    */
   QUERY_FAIL(403, "查询失败"),
   /**
    * 未知异常
    */
   UNKOWN_ERROR(404,"未知异常"),
   
   SERVER_ACCESS_FAIL(405, "服务器访问失败");

   /**
    * 响应代码
    */
   private final int code;

   /**
    * 响应消息
    */
   private final String message;

   CodeEnum(int _code, String _message) {

      this.code = _code;
      this.message = _message;

   }

   public int getCode() {
      return code;
   }

   public String getMessage() {
      return message;
   }

   /**
    * 通过枚举code获取对应的message
    * 
    * @return 取不到时返回null
    * @create 2018-4-28
    * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
    */
   public static String getMessageByCode(int code) {
      for (CodeEnum _enum : values()) {
         if (_enum.getCode() == code) {
            return _enum.getMessage();
         }
      }
      return null;
   }

   /**
    * 通过枚举code获取枚举对象
    * 
    * @return 取不到时返回null
    * @create 2018-4-28
    * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
    */
   public static CodeEnum getByCode(int code) {
      for (CodeEnum _enum : values()) {
         if (_enum.getCode() == code) {
            return _enum;
         }
      }
      return null;
   }

}
响应结果处理类:
package com.jd.ccc.sys.biz.yb.mall.common.res;

import com.jd.ccc.sys.biz.yb.mall.common.enums.CodeEnum;

import lombok.Data;
import lombok.ToString;

/**
 * 响应结果
 * 
 * @create 2018-4-28
 * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
 */
@Data
@ToString
public class CommonResult {
   /**
    * 应答码
    * 
    * @see 默认值为操作成功
    */
   private int code = CodeEnum.SUCCESS.getCode();
   /**
    * 应答码描述
    * 
    * @see 默认值为操作成功
    */
   private String message = CodeEnum.SUCCESS.getMessage();
   /**
    * 应答数据体
    * 
    * @see 可以为空
    */
   private Object data;
   
   /**
    * 京东账号
    * 
    * @see 可以为空
    */
   private String jdPin;

   public CommonResult() {
      this(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage(), null);
   }

   public CommonResult(CodeEnum codeEnum) {
      this(codeEnum.getCode(), codeEnum.getMessage(), null);
   }

   /**
    * 默认返回的code=CodeEnum.SUCCESS.getCode()
    */
   public CommonResult(Object data) {
      this(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage(), data);
   }

   /**
    * 默认返回的data=null
    */
   public CommonResult(int code, String message) {
      this(code, message, null);
   }

   public CommonResult(int code, String message, Object data) {
      this.code = code;
      this.message = message;
      this.data = data;
   }

}
控制层异常拦截:

package com.jd.ccc.sys.biz.yb.mall.web.controller.error;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jd.ccc.sys.biz.yb.mall.common.res.CommonResult;
import com.jd.ccc.sys.biz.yb.mall.common.enums.CodeEnum;
import com.jd.ccc.sys.biz.yb.mall.common.exception.YbMallException;
import com.jd.ccc.sys.biz.yb.mall.common.exception.YbMallServiceException;

/**
 * 
 * Controller异常统一处理,因为需要让已经在线上运行的接口不受影响,所以本
 * 次异常处理只扫描“com.jd.ccc.sys.biz.yb.mall.web.controller.v1”包路径下的
 * Controller进行统一的“com.jd.ccc.sys.biz.yb.mall.common.exception.YbMall
 * Exception”和“com.jd.ccc.sys.biz.yb.mall.common.exception.YbMallServiceE
 * xception”这两类自定义异常处理。
 * 
 * @create 2018-4-28
 * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
 *
 */
@ControllerAdvice(basePackages = "com.jd.ccc.sys.biz.yb.mall.web.controller.v1")
public class ExceptionAspect {

   /**
    * 
    * 统一处理JSON响应结果的错误结果 例如:{"code":201,message:"入参异常",data:null}
    * 
    * @param cause
    *            {@link Throwable} 异常
    * @param request
    *            {@link HttpServletRequest} 请求
    * @return {@link CommonResult} 响应结果
    * 
    * @create 2018-4-28
    * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
    */
   @ResponseBody
   @ExceptionHandler({YbMallException.class, YbMallServiceException.class })
   public CommonResult process(Throwable cause, HttpServletRequest request) {
      CommonResult result = new CommonResult();
      // 判断抛出异常是否为YbMallException
      if (cause instanceof YbMallException) {
         result.setMessage(cause.getMessage());
         result.setCode(((YbMallException) cause).getCode());
      } else {
         result.setCode(CodeEnum.ERROR.getCode());
         result.setMessage(CodeEnum.ERROR.getMessage());
      }
      return result;
   }

}

说明:拦截控制层抛出的YbMallException和YbMallServiceException异常。

Controller前的通讯异常等处理:

package com.jd.ccc.sys.biz.yb.mall.web.controller.error;

import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jd.ccc.sys.biz.yb.mall.common.enums.CodeEnum;
import com.jd.ccc.sys.biz.yb.mall.common.res.CommonResult;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by wangtianhong1 on 2017/7/6.
 */
@Controller
public class ExceptionController implements ErrorController {

    private static final String ERROR_PATH = "/error";

    @RequestMapping(value=ERROR_PATH,produces = {"text/html"})
    public String errorHtml(HttpServletRequest request){
        HttpStatus statusVal = getStatus(request);
        String errorUrl="redirect:/";
        switch (statusVal.value()) {
            case 401: return errorUrl;//重定向首页
            case 404: return errorUrl;
            case 500: return "redirect:https://www.jd.com/error2.aspx";
            default: return  errorUrl;
        }
    }
    
   /**
    * 
    * 针对JSON数据的异常处理
    * 
    * @param request
    *            请求
    * @return {@link CommonResult}
    * @create 2018-5-15
    * @author zhangqiang200<https://blog.csdn.net/zhangqiang_accp>
    */
   @RequestMapping(value = ERROR_PATH)
   @ResponseBody
   public CommonResult errorJson(HttpServletRequest request) {
      return new CommonResult(CodeEnum.ERROR);
   }


    /**
     * 获取错误状态编码
     * @param request
     */
    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request
                .getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        try {
            return HttpStatus.valueOf(statusCode);
        }
        catch (Exception ex) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
    }

    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值