项目中统一处理抛出异常,不影响用户体验

 

先整体说一下思路:

当程序中:我们抛出自定异常,如

    throw new BaseException(10002006);

那么BaseException类中利用方法,

    public BaseException(int code) {
        this(code, ResBundle.getMessage(String.valueOf(code)));

    }

将配置文件中的错误信息存到改异常中,然后由继承HandlerExceptionResolver的ExceptionResolver拦截,向用户展示友好界面。

备注:之后又接触了一个更加简单处理Controller层异常的方法,利用@ControllerAdvice与@ExceptionHandler注解处理。

@ControllerAdvice
public class MyExceptionHandler {
	
	@ResponseBody
	@ExceptionHandler(value=Exception.class)
	public Map<String,Object> errorHandler(Exception ex){
		Map<String,Object> map=new HashMap();
		map.put("code", -1);
		map.put("msg", ex.getMessage());
		return map;
	}
}

 

 

 

 

新建异常处理类,要继承HandlerExceptionResolver。

@Component
public class ExceptionResolver implements HandlerExceptionResolver {
    private final Logger logger = LoggerFactory.getLogger(ExceptionResolver.class);

    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception e) {
        String errorMessage = null;
        if (e instanceof BaseException) {
            errorMessage = e.getMessage();
        } else if (e instanceof UnauthorizedException) {
            errorMessage = "没有权限";
        } else if (e instanceof MaxUploadSizeExceededException) {
            errorMessage = "文件太大啦!<br>请选择更小一些的文件重试!";
        } else if (e instanceof RuntimeException && e.getCause() instanceof BaseException) {
            errorMessage = e.getCause().getMessage();
        } else {
            logger.error(e.getMessage(), e);
            errorMessage = "未知错误,请联系管理员!";
        }

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("status", false);

        result.put("msg", (Strings.isBlank(errorMessage) ? "未知错误,请联系管理员!" : errorMessage));

        if (HttpUtils.isAjaxRequest(request)) {
            return new ModelAndView(new FastJsonJsonView(), result);
        }

        if (handler instanceof HandlerMethod) {
            if (HttpUtils.isJsonResponse(request, (HandlerMethod) handler)) {
                return new ModelAndView(new FastJsonJsonView(), result);
            }
        }

        // 页面指定状态为500,便于上层的resion或者nginx的500页面跳转,由于error/error不适合对用户展示
        // response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return new ModelAndView("error/500", result);
    }

}

其中的BaseException类是项目中所以自定义异常都要继承的。

/**
 * 
 * 异常基类,所有异常都必须继承于此异常 . <br/>
 */
public class BaseException extends RuntimeException {

    private static final long serialVersionUID = -5875371379845226068L;

    /**
     * 具体异常码
     */
    protected int code;

    protected BaseException() {
        super();
    }

    public int getCode() {
        return code;
    }

    /**
     * 实例化异常
     * 
     * @param msgFormat
     * @param args
     * @return
     */
    protected BaseException newInstance(String msgFormat, Object... args) {
        return new BaseException(this.code, msgFormat, args);
    }

    public BaseException(int code) {
        this(code, ResBundle.getMessage(String.valueOf(code)));
    }

    public BaseException(int code, Object... args) {
        this(code, ResBundle.getMessage(String.valueOf(code)), args);
    }

    protected BaseException(int code, String msgFormat, Object... args) {
        super(String.format(msgFormat, args));
        this.code = code;
    }

    protected BaseException(String message, Throwable cause) {
        super(message, cause);
    }

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

    protected BaseException(String message) {
        super(message);
    }

}

 

当我们抛出自定义异常时,我们利用自定义的ResBundle(其中封装了ResourceBundle的一些信息),

ResourceBundle是去读取配置文件的。

public class ResBundle {
    private static Log log = LogFactory.getLog(ResBundle.class);

    private static Map<String, ResourceBundle> resMap = new HashMap<String, ResourceBundle>();

    private static final ResourceBundle NULL_BUNDLE = new ResourceBundle() {
        public Enumeration<String> getKeys() {
            return null;
        }

        protected Object handleGetObject(String key) {
            return null;
        }

        public String toString() {
            return "NULL_BUNDLE";
        }
    };

    private static ResourceBundle getBundle(String resourceName) {
        ResourceBundle rb = resMap.get(resourceName);
        if (rb == null) {
            try {
                rb = ResourceBundle.getBundle(resourceName, Locale.getDefault());
                if (rb == null) {
                    rb = NULL_BUNDLE;
                }
                resMap.put(resourceName, rb);
            } catch (Throwable mre) {
                log.error("No resource property file in the classpath or in the res folder.", mre);
            }
        }
        return rb;
    }

    public static String getString(String key) {
        return getResString("resource", key, null);
    }

    public static String getMessage(String key) {
        return getResString("resource", key, null);
    }

    public static String getString(String key, String defaultValue) {
        return getResString("resource", key, defaultValue);
    }

    public static String getMessage(String key, String defaultValue) {
        return getResString("resource", key, defaultValue);
    }

    public static String getResString(String resourceName, String key) {
        return getResString(resourceName, key, null);
    }

    public static String getResString(String resourceName, String key, String defaultValue) {
        String value = getBundle(resourceName).getString(key).trim();
        return Strings.isBlank(value) ? defaultValue : value;
    }

}

配置错误信息如图。

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值