springboot实现全局异常处理及自定义异常类

网友投稿 1509 2022-10-28

springboot实现全局异常处理及自定义异常类

springboot实现全局异常处理及自定义异常类

目录全局异常处理及自定义异常类全局异常处理定义一个业务异常的枚举全局异常处理配置springbootRestful使用springboot返回ModelAndView

全局异常处理及自定义异常类

全局异常处理

定义一个处理类,使用@ControllerAdvice注解。

@ControllerAdvice注解:控制器增强,一个被@Component注册的组件。

配合@ExceptionHandler来增强所有的@requestMapping方法。

例如:@ExceptionHandler(Exception.class)  用来捕获@requestMapping的方法中所有抛出的exception。

代码:

@ControllerAdvice

public class GlobalDefultExceptionHandler {

//声明要捕获的异常

@ExceptionHandler(Exception.class)

@ResponseBody

public String defultExcepitonHandler(HttpServletRequest request,Exception e) {

return “error”;

}

}

这样,全局异常处理类完毕。可以添加自己的逻辑。

然后还有一个问题,有的时候,我们需要业务逻辑时抛出自定义异常,这个时候需要自定义业务异常类。

定义class:BusinessException ,使他继承于RuntimeException.

说明:因为某些业务需要进行业务回滚。但spring的事务只针对RuntimeException的进行回滚操作。所以需要回滚就要继承RuntimeException。

public class BusinessException extends RuntimeException{

}

然后,现在来稍微完善一下这个类。

当我们抛出一个业务异常,一般需要错误码和错误信息。有助于我们来定位问题。

所以如下:

public class BusinessException extends RuntimeException{

//自定义错误码

private Integer code;

//自定义构造器,只保留一个,让其必须输入错误码及内容

public BusinessException(int code,String msg) {

super(msg);

this.code = code;

}

public Integer getCode() {

return code;

}

public void setCode(Integer code) {

this.code = code;

}

}

这时候,我们发现还有一个问题,如果这样写,在代码多起来以后,很难管理这些业务异常和错误码之间的匹配。所以在优化一下。

把错误码及错误信息,组装起来统一管理。

定义一个业务异常的枚举

public enum ResultEnum {

UNKONW_ERROR(-1,"未知错误"),

SUCCESHFIMApS(0,"成功"),

ERROR(1,"失败"),

;

private Integer code;

private String msg;

ResultEnum(Integer code,String msg) {

this.code = code;

this.msg = msg;

}

public Integer getCode() {

return code;

}

public String getMsg() {

return msg;

}

}

这个时候,业务异常类:

public class BusinessException extends RuntimeException{

private static final long serialVersionUID = 1L;

private Integer code; //错误码

public BusinessException() {}

public BusinessException(ResultEnum resultEnum) {

super(resultEnum.getMsg());

this.code = resultEnum.getCode();

}

public Integer getCode() {

return code;

}

public void setCode(Integer code) {

this.code = code;

}

}

然后再修改一下全局异常处理类:

@ControllerAdvice

public class GlobalDefultExceptionHandler {

//声明要捕获的异常

@ExceptionHandler(Exception.class)

@ResponseBody

public Result> defultExcepitonHandler(HttpServletRequest request,Exception e) {

e.printStackTrace();

if(e instanceof BusinessException) {

Log.error(this.getClass(),"业务异常:"+e.getMessage());

BusinessException businessException = (BusinessException)e;

return ResultUtil.error(businessException.getCode(), businessException.getMessage());

}

//未知错误

return ResultUtil.error(-1, "系统异常:\\n"+e);

}

}

判断这个是否是业务异常。和系统异常就可以分开处理了。

全局异常处理配置

springboot Restful使用

@ControllerAdvice、@ExceptionHandler、@ResponseBody实现全局异常处理

@ControllerAdvice 注解定义全局异常处理类@ExceptionHandler 指定自定义错误处理方法拦截的异常类型

同一个异常被小范围的异常类和大范围的异常处理器同时覆盖,会选择小范围的异常处理器

1.定义异常业务类

/**

* 异常VO

*

* @date 2017年2月17日

* @since 1.0.0

*/

public class ExceptionVO {

private String errorCode;

private String message;

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

public String getErrorCode() {

return errorCode;

}

public void setErrorCode(String errorCode) {

this.errorCode = errorCode;

}

}

2.定义自定义异常

package exception;

/**

* 无数据Exception

*

* @date 17/4/25

* @since 1.0.0

*/

public class NotFoundException extends SystemException {

public NotFoundException(String message) {

super(message);

}

}

/**

* 系统异常

*

* @date 2017年2月12日

* @since 1.0.0

*/

public class SystemException extends RuntimeException {

private static final long serialVersionUID = 1095242212086237834L;

protected Object errorCode;

protected Object[] args;

public SystemException() {

super();

}

public SystemException(String message, Throwable cause) {

super(message, cause);

}

public SystemException(String message) {

super(message);

}

public SystemException(String message, Object[] args, Throwable cause) {

super(message, cause);

this.args = args;

}

public SystemException(String message, Object[] args) {

super(message);

this.args = args;

}

public SystemException(Object errorCode, String message, Throwable cause) {

super(message, cause);

this.errorCode = errorCode;

}

public SystemException(Object errorCode, String message) {

super(message);

this.errorCode = errorCode;

}

public SystemException(Object errorCode, String message, Object[] args, Throwable cause) {

super(message, cause);

this.args = args;

this.errorCode = errorCode;

}

public SystemException(Object errorCode, String message, Object[] args) {

super(message);

this.args = args;

this.errorCode = errorCode;

}

public SystemException(Throwable cause) {

super(cause);

}

public Object[] getArgs() {

return args;

}

public Object getErrorCode() {

return errorCode;

}

}

3.定义全局异常处理类

import java.util.HashMap;

import java.util.Map;

import java.util.stream.Collectors;

import NotFoundException;

import org.apache.commons.collections.CollectionUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.MessageSource;

import org.springframework.context.NoSuchMessageException;

import org.springframework.context.i18n.LocaleContextHolder;

import org.springframework.http.HttpStatus;

import org.springframework.validation.BindException;

import org.springframework.validation.FieldError;

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.ResponseStatus;

import ExceptionVO;

/**

* WEB异常处理器

*

* @date 2017年2月16日

* @since 1.0.0

*/

@ControllerAdvice("web") //指定异常处理期拦截范围

public class WebExceptionHandler {

static Logger LOG = LoggerFactory.getLogger(WebExceptionHandler.class);

@Autowired

private MessageSource messageSource;

@ExceptionHandler(FieldException.class)

@ResponseStatus(HttpStatus.CONFLICT) //指定http响应状态

@ResponseBody

/**

* 未找到数据

*

* @param e

* @return

*/

@ExceptionHandler(NotFoundException.class)//指定异常类型

@ResponseStatus(HttpStatus.NOT_FOUND)

@ResponseBody

public ExceptionVO handleNotFoundException(NotFoundException e) {

ExceptionVO vo = new ExceptionVO();

fillExceptionVO(e, vo);

return vo;

}

@ExceptionHandler(SystemException.class)

@ResponseStatus(HttpStatus.CONFLICT)

@ResponseBody

public ExceptionVO handleSystemException(SystemException e) {

ExceptionVO vo = new ExceptionVO();

fillExceptionVO(e, vo);

return vo;

}

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)

@ExceptionHandler(Exception.class)

public void globalError(Exception e) {

LOG.error(e.getMessage(), e);

}

/**

* 填充异常响应消息

*

* @param e

* @param vo

*/

private void fillExceptionVO(SystemException e, ExceptionVO vo) {

if (e.getMessage() != null) {

String message = e.getMessage();

try {

message = messageSource.getMessage(e.getMessage(), e.getArgs(), LocaleContextHolder.getLocale());

} catch (NoSuchMessageException ex) {

; // ignore

}

vo.setMessage(message);

}

vo.setErrorCode(String.valueOf(e.getErrorCode()));

}

}

springboot 返回 ModelAndView

package exception.handler;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerExceptionResolver;

import org.springframework.web.servlet.ModelAndView;

@Commpent

public class OverallExceptionHandler implements HandlerExceptionResolver {

@Override

public ModelAndView resolveException(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,

Exception ex) {

ModelAndView mav = new ModelAndView();

System.out.println(ex.getMessage());

mav.addObject("errMsg", ex.getMessage());

mav.setViewName("error");

return mav;

}

}

其它方式:

@ControllerAdvice

public class GlobalExceptionHandler {

@ExceptionHandler(value = Exception.class)

public ModelAndView resolveException(HttpServletRequest request, Exception ex) throws Exception {

ModelAndView mav = new ModelAndView();

System.out.println(ex.getMessage());

mav.addObject("errMsg", ex.getMessage());

mav.setViewName("error");

return mav;

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:基于 Unittest 和 Requests 的 接口自动化测试框架
下一篇:TP5 assign给模板变量赋值(或者取得参数值,在模板中显示出来)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~