全局异常捕获处理

自定义一个异常类,用户抛出异常后根据组装成前台需要的格式进行返回

1.自定义异常类

package com.ztccloud.naire.exception;

import lombok.Data;

@Data
public class QuestionException extends RuntimeException {
    /**
     * 异常码
     */
    private String errorCode;

    /**
     * 异常信息
     */
    private String msg;

    public QuestionException(String errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
        this.msg = message;
    }

    public QuestionException() {
    }

    public QuestionException(Throwable cause) {
        super(cause);
    }

    public QuestionException(String message) {
        super(message);
        this.msg = message;
    }
}

2.异常处理类

import com.ztccloud.naire.config.ErrorProperties;
import com.ztccloud.naire.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.Optional;

@Slf4j
@RestControllerAdvice//配置一个切面,主要用于Exception
public class QuestionExceptionHandler {

    private static final String DEFAULT_CODE = "ques_500";

    private static final String PARAM_NOT_VALID = "ques_501";

    private static final String DEFAULT_MSG = "系统异常";

    @ExceptionHandler(QuestionException.class)//异常处理器
    public Result<String> datacenterExceptionHandler(QuestionException e) {
        log.error("", e);
        Result<String> of = Result.of();
        String code = e.getErrorCode();
        if (StringUtils.isEmpty(code)) {
            code = DEFAULT_CODE;
        }
        return of.setMsg(Optional.ofNullable(ErrorProperties.p.getProperty(code))
                        .orElseGet(() -> ErrorProperties.p.getProperty(DEFAULT_CODE)))
                .setCode(code);
    }

    @ExceptionHandler(Exception.class)
    public Result<String> exceptionHandler(Exception e) {
        log.error("system exception:", e);
        Result<String> of = Result.of();
        return of.setMsg(DEFAULT_MSG).setCode(DEFAULT_CODE);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> paramExceptionHandler(BindException e) {
        List<FieldError> fieldErrors = e.getFieldErrors();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < fieldErrors.size(); i++) {
            FieldError error = fieldErrors.get(i);
            sb.append("[").append("参数:").append(error.getField()).append(" -> ").append(error.getDefaultMessage()).append("]");
            if (i != fieldErrors.size() - 1) {
                sb.append("\r\n");
            }
        }
        Result<String> of = Result.of();
        return of.setMsg(sb.toString()).setCode(PARAM_NOT_VALID);
    }
}

3.用于捕获filter异常的类

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;


@RestController
public class ErrorController {

    public static final String ERROR_PATH = "/error/throw";

    public static final String ATTRIBUTE = "filter.error";

    @RequestMapping(ERROR_PATH)
    public void reThrow(HttpServletRequest request) throws Exception {
        throw ((Exception) request.getAttribute(ATTRIBUTE));
    }
}

4.接口统一响应类

import lombok.Data;
import lombok.experimental.Accessors;

/**
 * 接口统一响应类
 */
@Data
@Accessors(chain = true)
public class Result<T> {
    /**
     * 默认返回200, 表示成功处理;其他错误码在统一异常类返回
     */
    private String code = "200";

    /**
     * 返回数据
     */
    private T data;

    /**
     * 提示信息
     */
    private String msg;

    private Result() {
    }

    private Result(String msg) {
        this.msg = msg;
    }

    private Result(T data) {
        this.data = data;
    }

    private Result(T data, String msg) {
        this.data = data;
        this.msg = msg;
    }

    public static <T> Result<T> of() {
        return new Result<T>();
    }

    public static <T> Result<T> of(T data) {
        return new Result<>(data);
    }

    public static <T> Result<T> of(T data, String msg) {
        return new Result<>(data, msg);
    }
}

然后在项目中,抛出异常,如下在filter中抛出异常

@Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws  ServletException, IOException {
            HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
            HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

            String url = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
            if (patterns.contains(url)|| StringUtils.containsAny(url,new String[]{"swagger","api-docs"})) {
                //在白名单中的url,放行访问
                filterChain.doFilter(httpRequest, httpResponse);
                return;
            }
            RecordUser user=(RecordUser) httpRequest.getSession().getAttribute(UserControl.SESSION_USER);
            if (user != null) {
                //若为登录状态 放行访问
                UserControl.setUser(user);
                filterChain.doFilter(httpRequest, httpResponse);
            } else {
                //提示用户未进行登录
                try {
                    throw new QuestionException("ques_user_1001","User not logged in!");
                } catch (Exception e) {
                    servletRequest.setAttribute(ErrorController.ATTRIBUTE, e);
                    servletRequest.getRequestDispatcher(ErrorController.ERROR_PATH).forward(servletRequest, servletResponse);
                }
            }

        }

加载项目的时候,加载错误信息文件

@Component
public class ErrorProperties {
    public static Properties p = new Properties();

    private static final Logger log = LoggerFactory.getLogger(ErrorProperties.class);

    @PostConstruct
    public void parseErrorProperties() throws IOException {
        log.info("load error.properties ...");
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("error.properties");
        try {
            p.load(in);
        } catch (IOException e) {
            log.error("load error.properties failed...", e);
            throw e;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值