20190725 全局异常处理器

全局异常设计的好坏,关系到整个系统的健壮性,需要能够适配所有微服务项目。

@ControllerAdvice+@ExceptionHandler全局处理Controller层异常。

捕获controller层的异常,处理指定类型的异常;

返回前端一个ResponseEntity对象;

不足之处:只能处理Controller抛出的异常,对于Interceptor(拦截器)及其他层面的异常,无能为力。

 

1)在方法的后面使用throws关键字对外声明该方法有可能发生异常

2)调用者在调用方法时,就明确地知道该方法有异常,并且必须在程序中对异常进行处理,否则编译无法通过

3)编译时异常的特点是Java编译器会对其进行检查,如果出现异常就必须对异常进行处理,否则程序无法编译通过。

4)运行时异常一般是程序中的逻辑错误引起的,在程序运行时无法修复。例如 数据取值越界。

5)自定义异常,项目中也有自定义异常类啊,全局异常设计。在Java中允许用户自定义异常,但自定义的异常类必须继承自Exception或其子类。

 

出现异常,返回给前端一个ResponseEntity对象,里面包含异常信息。

是否需要区分异常级别?

package com.yunque.www.springbootdemo.exceptions;

import com.yunque.www.springbootdemo.pojo.BaseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;


//@ControllerAdvice(annotations = RestController.class)
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private String JSON_FORMAT_TEMP = "{\"code\": \"%s\",\"message\": \"%s\",\"from\": \"%s\",\"path\": \"%s\"}";
    private HttpHeaders headers = null;

    public GlobalExceptionHandler() {
        this.headers = new HttpHeaders();
        this.headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
    }

    /**
     * 是否要区分异常级别,是error级别还是warn级别?
     *
     * @param serviceException
     * @param request
     * @return
     */
    @ExceptionHandler(value = ServiceException.class)
    public ResponseEntity<BaseResult> handlerServiceException(ServiceException serviceException, HttpServletRequest request) {
        return processException(serviceException.getCode(), serviceException.getMessage(), serviceException, request, Level.ERROR);
    }

    @ExceptionHandler(value = SystemException.class)
    public ResponseEntity<BaseResult> handlerSystemException(SystemException systemException, HttpServletRequest request) {
        //如果日志文件中错误码为500000,系统级异常
        return processException(PicaResultCode.SYSTEM_EXCEPTION.getCode(), PicaResultCode.SYSTEM_EXCEPTION.getMessage(), systemException, request, Level.ERROR);
    }

    /**
     * 处理异常信息
     *
     * @param code
     * @param message
     * @param exception
     * @param request
     * @param level
     * @return
     */
    private ResponseEntity<BaseResult> processException(String code, String message, Exception exception, HttpServletRequest request, Level level) {
        String json = String.format(JSON_FORMAT_TEMP, code, message, request.getRemoteAddr(), request.getRequestURI() + "?" + request.getQueryString());
        if (level == Level.ERROR) {
            logger.error(json, exception);
        }
        //todo:返回给前端一个ResponseEntity对象,里面包含错误的信息
        return new ResponseEntity<BaseResult>(new BaseResult().Builder().setCode(code).setMessage(message).build(), headers, HttpStatus.OK);
    }

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
        logger.error(ex.getMessage(), ex);
        if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
            request.setAttribute("javax.servlet.error.exception", ex, WebRequest.SCOPE_REQUEST);
        }
        return new ResponseEntity<Object>(body, headers, status);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值